Raisonance Ride7 & ARM Tools (17) LPC2xxx の Startup (1) ― 2012年09月20日 20時23分53秒
以前から気になっていた LPC2xxx 用の Startup。RAISONANCE forums でも時々問題になっていた。この際少し調べてみることにする。
RAISONANCE オリジナルの Startup をそのまま使うと、どうやってもうまく動かない。
これは crt0_LPC23x.s の割り込みエントリー部分に不具合があるためで、その部分を使わなければ
ここではせっかくなので、問題の割り込みエントリー部分をそのまま使う方法を考える。
もちろん一部修正は必要だ。
それでは修正の必要な crt0_LPC23x.s から
次にリンカースクリプト LPC23_512K_64K.ld 、これは Ride7 が自動的に作成した物をひとつにまとめた。(スクリプトファイル(GNUtools.js) の一部変更が必要)
スクリプトファイルにも一部不具合があるのでこの際修正しておこう。
C:\Program Files\Raisonance\Ride\Scripts\GNUtools.js
前置きがずいぶん長くなってしまった。
今日の所はこの辺にしておこう。
環境:CQ-FRK-NXP-ARM
+ Ride7 version 7.30.10.0169
+ RKit-ARM version 1.30.10.0356
+ GCC Sourcery CodeBench Lite 2012.03-56
RAISONANCE オリジナルの Startup をそのまま使うと、どうやってもうまく動かない。
これは crt0_LPC23x.s の割り込みエントリー部分に不具合があるためで、その部分を使わなければ
__attribute__ ((interrupt("IRQ"))) void IRQHandler(void) { if((T0IR &1) ==1){ FIO1PIN2 ^= 0x04; T0IR=1; } }上記のように普通に書いて問題ない。
ここではせっかくなので、問題の割り込みエントリー部分をそのまま使う方法を考える。
もちろん一部修正は必要だ。
それでは修正の必要な crt0_LPC23x.s から
次にリンカースクリプト LPC23_512K_64K.ld 、これは Ride7 が自動的に作成した物をひとつにまとめた。(スクリプトファイル(GNUtools.js) の一部変更が必要)
スクリプトファイルにも一部不具合があるのでこの際修正しておこう。
C:\Program Files\Raisonance\Ride\Scripts\GNUtools.js
前置きがずいぶん長くなってしまった。
今日の所はこの辺にしておこう。
環境:CQ-FRK-NXP-ARM
+ Ride7 version 7.30.10.0169
+ RKit-ARM version 1.30.10.0356
+ GCC Sourcery CodeBench Lite 2012.03-56
Raisonance Ride7 & ARM Tools (17) LPC2xxx の Startup (2) ― 2012年09月25日 19時35分42秒
さて、それでは本題に入っていこう。
Raisonance の Startup を使ってうまくいかない原因のひとつはエントリー部分に割り込み専用の処理がしてあるにもかかわらず __attribute__ ((interrupt("IRQ"))) などを使ってしまうことだ。従って、割り込みエントリーを使うなら属性指定をしてはならない。
もうひとつの原因はエントリー部分からハンドラをコールしなければならないにもかかわらずジャンプしてしまっていることだ。よって、コールに変更する。
さらにもうひとつあげるとするなら Raisonance の場合、通常スタートアップは $(RkitLib)\ARM\ から crt0_LPC23x.o の形でリンクするのでハンドラを weak 指定にしたほうがよい、といったところだろうか。
まずは IRQ を使った割り込み。
① main_irq1.c 割り込みが入ると IRQ_Handler をコールしてくるのでこの関数の中で割り込み先を特定し、さらにそこへ分岐していく。
次に、VicVectAddr を使った割り込み。
② main_irq2.c 同じ IRQ 割り込みでも VICVectAddr に予め関数を登録しておけば割り込み先を特定する作業をすることなく呼び出すことができる。
続いて FIQ を使った割り込み。
③ main_fiq.c ① の IRQ 割り込みと似ている。
最後は VICVectAddr をベクターテーブルに組み込んだ割り込み。
この時 crt0_LPC23x.s は以下の変更をする。
④ main_vic.c ベクターテーブルからいきなり VICVectAddr を参照する。
見たところ④の方法がすっきりして無駄がないように見える。
後試してみたいのは SWI_Handler だがどのようにして試そうか思案中だ。
環境:CQ-FRK-NXP-ARM
+ Ride7 version 7.30.10.0169
+ RKit-ARM version 1.30.10.0356
+ GCC Sourcery CodeBench Lite 2012.03-56
Raisonance の Startup を使ってうまくいかない原因のひとつはエントリー部分に割り込み専用の処理がしてあるにもかかわらず __attribute__ ((interrupt("IRQ"))) などを使ってしまうことだ。従って、割り込みエントリーを使うなら属性指定をしてはならない。
もうひとつの原因はエントリー部分からハンドラをコールしなければならないにもかかわらずジャンプしてしまっていることだ。よって、コールに変更する。
さらにもうひとつあげるとするなら Raisonance の場合、通常スタートアップは $(RkitLib)\ARM\ から crt0_LPC23x.o の形でリンクするのでハンドラを weak 指定にしたほうがよい、といったところだろうか。
まずは IRQ を使った割り込み。
① main_irq1.c 割り込みが入ると IRQ_Handler をコールしてくるのでこの関数の中で割り込み先を特定し、さらにそこへ分岐していく。
次に、VicVectAddr を使った割り込み。
② main_irq2.c 同じ IRQ 割り込みでも VICVectAddr に予め関数を登録しておけば割り込み先を特定する作業をすることなく呼び出すことができる。
続いて FIQ を使った割り込み。
③ main_fiq.c ① の IRQ 割り込みと似ている。
最後は VICVectAddr をベクターテーブルに組み込んだ割り込み。
この時 crt0_LPC23x.s は以下の変更をする。
ldr PC, [PC, #-0x0120] これを有効にして(lpc21x Lpc22x の場合は 0x0FF0) ldr PC, =IRQHandler これをコメントにする。この方法は Startup のエントリー部分を使わないので割り込み処理ルーチンに __attribute__ ((interrupt("IRQ"))) が必要だ。
④ main_vic.c ベクターテーブルからいきなり VICVectAddr を参照する。
見たところ④の方法がすっきりして無駄がないように見える。
後試してみたいのは SWI_Handler だがどのようにして試そうか思案中だ。
環境:CQ-FRK-NXP-ARM
+ Ride7 version 7.30.10.0169
+ RKit-ARM version 1.30.10.0356
+ GCC Sourcery CodeBench Lite 2012.03-56
Raisonance Ride7 & ARM Tools (17) LPC2xxx の Startup (3) ― 2012年09月26日 20時04分26秒
SWI_Handler 、なかなか手ごわかった。
結局Cとインラインアセンブラが混在する形になってしまった。さらに crt0_LPC23x.s にも修正を加えなければならなくなった。テストのためのテストだからいいことにしよう。
では、さっそく crt0_LPC23x.s の修正部分を見てみよう。
そして SWI 割り込みサンプル。main_swi.c
SWI_Handler を呼び出す部分をCでどのようにすればよいのか分からなかったのでインラインアセンブラでそのまま書いている。実際に使う場合は NXP サンプル swi_handler.s のようにするのがよいだろう。
いろいろやってわかった事、割り込みのエントリー部分はじゃまなだけで必要ないということだ。さっさと削除してしまおう。そのほうがすっきりして分かりやすくなる。
環境:CQ-FRK-NXP-ARM
+ Ride7 version 7.30.10.0169
+ RKit-ARM version 1.30.10.0356
+ GCC Sourcery CodeBench Lite 2012.03-56
結局Cとインラインアセンブラが混在する形になってしまった。さらに crt0_LPC23x.s にも修正を加えなければならなくなった。テストのためのテストだからいいことにしよう。
では、さっそく crt0_LPC23x.s の修正部分を見てみよう。
SWIHandler: SaveContext r0,r12 /*; Save the workspace plus the current*/ /*; return address lr_ svc and spsr_svc.*/ ldr r0, [lr, #-4] /*; Get swi code.*/ and r0, #0xFF bl SWI_Handler /*; Branch to SWI_Handler.*/ RestoreContext r0,r12 /*; Return to the instruction following...*/ /*; ...the SWI instruction.*/赤で記したのが追加した部分になる。SWI コードを取り出すためのものだがこれをコール先に持ち込むことができなかった。
そして SWI 割り込みサンプル。main_swi.c
SWI_Handler を呼び出す部分をCでどのようにすればよいのか分からなかったのでインラインアセンブラでそのまま書いている。実際に使う場合は NXP サンプル swi_handler.s のようにするのがよいだろう。
いろいろやってわかった事、割り込みのエントリー部分はじゃまなだけで必要ないということだ。さっさと削除してしまおう。そのほうがすっきりして分かりやすくなる。
環境:CQ-FRK-NXP-ARM
+ Ride7 version 7.30.10.0169
+ RKit-ARM version 1.30.10.0356
+ GCC Sourcery CodeBench Lite 2012.03-56
最近のコメント