TOPPERS/JSP for armv4における例外ベクトルの扱い

TOPPERS/JSP 1.4.3のjsp/config/armv4サブディレクトリにはARM7TDMIプロセッサ共通のCPU依存部が置かれています。ここには、例外ハンドラや割り込みハンドラの登録機能も実装されていますが、それがわかりにくいためにメモを残しておきます。

例外ハンドラの登録

ARM7TDMIコアは、リセットや割り込みなどが発生すると0番地からはじまる例外ベクトルの命令を実行します。このベクトルには1エントリあたり1命令のみが格納され、通常は例外ハンドラ本体へのジャンプ命令が置かれます。

TOPPERS/JSP for armv4は、この例外ベクトルが書き込み可能であることを仮定しています。そのため、LPC2388ではメモリ・リマップを使ってSRAMの先頭64Byteを0番地にマッピングしています。当然ですが、リセット時には例外ベクトルはFlash ROMで無ければなりません。そうで無い場合は電源投入直後、SRAMの値は不定ですのでいきなり暴走することになります。

TOPPERS/JSP for LPC2388では、sys_initialize()関数の中からinit_vector()を呼び出して、この問題に対処します。init_vector()はFLASH上のベクトルをSRAMのリマップ領域にコピーした後、リマップを実行します。そのため、TOPPERS/JSP for LPC2388では、ベクトルは0番地からはじまる物としてメモリ上にデータを配置しています。リマップした後も同じデータがそこにありますので問題はありません。

例外ハンドラの生成と登録はコンフィグレーション・ファイルから行います。これを実現するため、以下の二つのマクロを cpu_config.h で提供しています。

  1. EXC_ENTRY
  2. EXCHDR_ENTRY

割り込みハンドラの登録

TOPPERS/JSP for LPC2388では、割り込みハンドラの登録をVICのベクトル要素ごとに行っています。つまり、32あるペリフェラル割り込みソースそれぞれがハンドラを持つことができます。ハンドラはC言語のサブルーチンそのものであり、呼び出し規約に特別な工夫は必要有りません。

そのための機能は jsp/config/armv4/_common_lpc2388/chip_config.h および chip_config.c の中で宣言しています。

  1. /*
  2. * 割込みハンドラの出入口処理の生成マクロ
  3. *
  4. */
  5. #define INTHDR_ENTRY(inthdr) extern void inthdr(void)
  6. #define INT_ENTRY(inthdr) inthdr
  7. /*
  8. * 割込みハンドラの設定
  9. *
  10. * 割込み番号 inhno の割込みハンドラの起動番地を inthdr に設定する.
  11. */
  12. extern void define_inh(INHNO inhno, FP inthdr);
  1. /*
  2. * 割込みハンドラの設定
  3. *
  4. * 割込み番号 inhno の割込みハンドラの起動番地を inthdr に設定する.
  5. * VICVectAddress[]は同名のレジスタ列にマップされている。したがって、
  6. * define_inhを呼ぶと、VICVectAddressXレジスタが初期化される。
  7. */
  8. void
  9. define_inh(INHNO inhno, FP inthdr)
  10. {
  11. assert(inhno <= MAX_INT_NUM);
  12. VICVectAddress[inhno] = (volatile FP*)inthdr;
  13. }

define_inhは、VICのベクトル・レジスタに関数の先頭アドレスを設定しているだけです。設定されたアドレスへのジャンプは jsp/config/armv4/_common_lpc2388/chip_support.S の中の IRQ_Handler が行います。そのため、IRQ_Handler を例外ベクトルのIRQエントリに設定しなければなりません。

この設定は先の例外ハンドラ設定を使いません。まったく異質のメカニズムになっているからです。TOPPERS/JSP for LPC2388では、この設定を sys_initialize() ルーチンの中で行っています。

結果的に、ユーザーはIRQ_Handlerの設定を意識する必要はありません。逆にIRQ例外ハンドラをユーザーが設定すると動作が不定になります。ユーザーは単にVICのエントリ毎にハンドラを用意してコンフィグレーション・ファイルの中で割り込みハンドラとして宣言します。