ATMEL社製JTAGICE3を使ったJTAGデバッグ方法の紹介
実際にマイコン上でプログラムを動作させながら、割込みや外部機器と連携した状況で、AVR の JTAG OCD を使ったデバッグができます。 これで、シミュレーションでは分かりにくいエラーを調べられます。
目次
AVRへの接続は、JTAGICE3をJTAGピン(8ピン)に接続します。 JTAGICE3とAVR間のピン接続は、JTAGICE3のページを参考にどうぞ。
AVRは、JTAGによるOCD(On-Chip Debugging)をサポートしている必要があります。 使用するAVRがJTAG OCDをサポートしているかは、データシートのJTAG欄をチェックしてください。 または、AVRStudioでヒューズ設定を開き、OCDENの設定があるかチェックしてください。 AVRによっては、debugWIREなど別のOCD用のデバッグ環境が提供されています。
今回の実験に使ったプログラムは、一番下に掲載しています。LEDの点滅回路に、INT0割込みを使ったサンプルコードです。
プログラムツールをJTAGICE3へ変更する。
プロジェクトプロパティのToolから、JTAGICE3へ変更し、インターフェースをJTAGにする。
IDEに、JTAG on JTAGICE3と表示されているか確認する。
IDE中央上の、Debugの左にある、Start Debuggin and Break をクリックか、Alt+F5を押して、デバッグを開始する。
自動的に、Flashへ書込み、FuseビットのOCDENをONにして、デバッグが開始される。
かならず、ソリューション構成がDebugになっていることを確認する。(もし、構成を変更している場合は、Debugモードが設定されているか確認すること) Releaseなど、デバッグ情報が無い場合は、ソースコードがありませんとアセンブラコードが表示される。
正しくコンパイルされると、初めのコードで停止する。IDE上のデバッガ制御ツールを使いデバッグを進める。
ステップ実行
デバッグに必要な情報は全て、ツールバーにあるデバッグの中にある。デバッグツールが表示されない場合や、ウィンドウを間違って消してしまった場合はこちらから表示できる。
デバッグ中で一時停止している時は、AVRマイコン内の状態を表示することが出来る。
他に、ソースコード上の変数にマウスカーソルを停止すると、現在値を表示したりできる。
ブレークポイントは、デバッグにおいて、最もよよく使うツールの1つで、 コードが実行されるときに一時的に中断させる位置を指定するためモノです。 停止させたい位置で、ブレークポイントを挿入し、不要になれば削除します。
編集中・デバッグ中に任意に設定でき、デバッグ終了後もブレークポイントは記憶されます。
IDEの右端をダブルクリックすると、ブレークポイントの設定・削除ができる。
/* * cega_INT0.c * * Author: cega * License: Public Domain * * Function: interrupt INT0(PD2) and blink LED(PA0) */ /* * I/O Information * * PA0: D Output: LED : blink by High * PD2: D Input : (Internal pullup/INT0) : switch - GND * */ #define F_CPU 1000000L #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> static void init_ioport( void ); volatile int interrupt_count = 0; int main(void) { init_ioport(); /* External Interrupt settings */ EICRA = _BV(ISC00); // ISCnx INTn x: 00: low level INT / 01: Any edge / 10: falling edge / 11: rising edge EIMSK = _BV(INT0); EIFR = _BV(INTF0); sei(); // enable interrupts PINA = _BV(PINA0); // toggle LED while(1) { if( 0 == interrupt_count % 2) { for( int i = 0; i<20 ; i++) _delay_ms(100); PINA = _BV(PINA0); // toggle LED }else{ for( int i = 0; i<5 ; i++) _delay_ms(100); PINA = _BV(PINA0); // toggle LED } } } ISR(INT0_vect) { interrupt_count++; } static void init_ioport( void ) { /* Port Digital I/O settings */ /* DDRx: 0: Input / 1: Output PORTx: Input : 0: pull-up disable / 1: pull-up enable Output: 0: Low / 1: High PINx: Read PINx: Pin status Write PINx: 1: PORTx の値を反転する 追記1: 電力最小化には、各ポートをRead/Pull-upにして、何も外部接続しない方が良い。 追記2: リセット時も電力最小化する場合は、各ポートに外部Pull-up/Pull-downを接続するのが良い。(デバイスにより違うので注意) */ DDRA = _BV(0); PORTA = ~_BV(PORTA0); DDRB = 0x00; PORTB = 0xff; DDRC = 0x00; PORTC = 0xff; DDRD = 0x00; PORTD = 0xff; }