なんとかメドが立ちました。
HOS側でEVBA(例外割り込みベクタテーブル)全体をオリジナルに書き換え、独自の例外機構を扱うように変更しました。
まだ不安要素や未実装がありますが、とりあえず公開。HOS本体はオフィシャルの方から入手する必要があります。対応バージョンは HOS v4 1.02 です。
hos-v4_102_avr32_support.zipをダウンロード (2次配布は禁止させていただきます)
このzipには以下のファイルが含まれます。
- AVR32用プロセッサ抽象化コンポーネント (include/avr32, src/avr32)
- AVR32用インクルードコードを追加した include/hosdenv.h
- AVR32用ライブラリ作成makefileとライブラリ (lib/avr32)
- カーネルのコード訂正 src/mknl/sys/mexe_sys.c (オフィシャルで報告済。v1.03以降で公式に訂正されます)
- hos4cfg のリリースビルド(MSVC6でコンパイル) (config/Release/hos4cfg.exe)
このHOSを利用するだけ(コード訂正しない)ならば、本体のinclude以下のファイルと、上記zipのinclude以下をマージしてAVR32のツールチェインの所に入れます。僕はkernel.hとかを標準のinclude先に混ぜてしまうのが嫌なので、
C:\Program Files\Atmel\AVR Tools\AVR32 Toolchain\avr32\include\hos-v4\include\...
にコピーしました。代わりに、AVR32Studioのプロジェクト設定でPathsに
${AVR32_HOME}/avr32/include/hos-v4/include
を追加する必要があります。
あとは toolchain/avr32/lib にライブラリファイル(dwarf-2形式デバッグ用 libh4avr32d.a、デバッグ情報なし libh4avr32.a)をコピーして完了です。
★割り込みの扱いについて
割り込みは本来の2048通り分岐を捨て、グループ毎の分岐としました。最大64通り。実際に使用されるグループはずっと少なく、AT32UC3B0256ならば 0~17 です。
割り込みの使用方法はできるだけHOS、というかμITRONの標準仕様に合わせるようにしました。詳しい方法は以下のリファレンスを参照してください。
●AVR32対応コードリファレンス
- 独自関数(HOS起動より前に呼ぶべきもの)
void set_sleep_function(FP pfn)
アイドルループで繰り返し呼び出される関数を設定する。sleep命令等を書いた関数(引数なし、戻り値なし)をpfnとして渡しておくと、アイドル時にスリープする。敢えてHOS内部でsleep命令を実装しないのは、sleep命令に引数があるから。
void set_supervisor_call(FP pfn)
スーパバイザーコール(scall命令)で呼び出される関数を設定する。
void set_interruptc_base(VP base)
割り込みレジスタのベース位置を設定する。各デバイスのio.hで定義される AVR32_INTC_ADDRESS をVPにキャストして渡せば良い。
- μITRONの使用に基づき追加実装した関数(HOS起動後に適宜呼び出すもの)
ER def_inh(INTNO intno, T_DINH *pk_dinh)
割り込みハンドラを定義(設定)する。intnoにはグループ番号(0~63)を指定する。また、pk_dinh->intatr には割り込み優先度(INT0~3)を0~3の整数で指定する。
なお、実際に割り込みが発生した時、割り込みハンドラのexinfにはライン番号(すなわち、割り込み発生要因 ICRn が指す IRR レジスタ値で最下位の1のビット位置 0~31) が渡される。例えば外部割り込みピン EXTINT[2] による割り込みが起きた場合、intno=1 (EIC) の割り込みハンドラが exinf = 2 で呼び出される。
ER def_exc(EXCNO excno, T_DEXC *pk_dexc)
例外ハンドラを定義(設定)する。excnoには例外番号(0~28)を指定する。
…の予定ですが、def_excはまだ実装されていません。^^;
- コンフィグレーションで必要な記述
HOS_MAX_INTNO(?)
割り込み番号の最大値(すなわち最大グループ番号)を指定する。
HOS_MAX_EXCNO(28)
CPU例外番号の最大値(28)を指定する。
例外番号とは、EVBAからのオフセットを4で割った値とする。たとえば、0=UnrecoverableException、4=NMI、8=IllegalOpecode、etc。
AVR32 Architecture Manialの7.3項で参照できます。
- コンパイルの仕方
- リンカオプションに -lh4avr32(d) を追加するだけ。必要に応じてincludeが通るようパスを追加指定すればよい。
ざっとこんなもん。例外の発生、割り込みの発生、タスクスイッチングについては確認済み。ただ例外あたりはまだバグがありそう。スーパバイザーコールに至ってはまだ確認もしてません(汗)。いや、まぁ、使わないし。
つっこみ、改善提案歓迎です。
コメントする