前回からの続きです。
このテーマを最初からご覧になる場合はこちらからどうぞ。
サンプルプロジェクトの説明
このページ(TOPPERS/ASPのビルドからデバッグまで~サンプルプロジェクトで遊ぼう)を参照してください。
AVR32版カーネルについて
以下、このカーネルにおける備考です。
●割り込み優先度
このカーネルでは、-1(優先度最低)から-4(優先度最高)の4段階の優先度設定が可能です。
マイコンというのは、割り込みが起こるとアプリケーションで使っていたレジスタの値をスタックという専用のメモリへ退避させます。
更に割り込み処理が終わると、処理がアプリケーションへ戻る前にスタックへ退避させた値をレジスタに復帰させなければなりません。
したがって、これらの一時退避するレジスタの数が多いと処理自体がオーバーヘッドになり、反応性が悪くなります。
レジスタの退避と復帰は、割り込みルーチンの冒頭と終盤一命令ずつ書いていかなきゃならない(仮に一時退避するレジスタの数が8個なら、退避と復帰で計16ステップ必要)からです。
そういうマイコンが多数派ですが、AVR32(正確には「AVR32 UC3」)の場合はレジスタの一時退避をハードウェアで自動的にやってくれます。
ハードウェアによる一時退避の処理は非常に速いため、このことは割り込みの反応性を大きく向上させます。
つまり、割り込みを多用するアプリケーションの性能が良いということです。
大変優れたアーキテクチャです!
●例外ハンドラ
例外ハンドラとしては「..\target\at32uc3a3_xpld_gcc\target_vector.S」の冒頭のコメントに記されたものを使用することができます。
番号は飛び飛びになっちゃっているのは注意です。
特に20番以降はヒドイ…。
- ...
- /*
- * ターゲット依存ベクターテーブル(AT32UC3A3-XPLD用)
- */
- #include <avr32/io.h>
- /*
- * CPU例外番号
- *
- *
- * 0 - Unrecoverable exception
- * 1 - TLB multiple hit
- * 2 - Bus error data fetch
- * 3 - Bus error instruction fetch
- * 4 - NMI
- * 5 - Instruction Address
- * 6 - ITLB Protection
- * 7 - Breakpoint
- * 8 - Illegal Opcode
- * 9 - Unimplemented instruction
- * 10 - Privilege violation
- * 12 - Coprocessor absent
- * 13 - Data Address (Read)
- * 14 - Data Address (Write)
- * 15 - DTLB Protection (Read)
- * 16 - DTLB Protection (Write)
- * 20 - ITLB Miss
- * 24 - DTLB Miss (Read)
- * 28 - DTLB Miss (Write)
- * 64 - Supervisor call
- */
- ...
例外ハンドラの動作は、サンプルプログラムで確認できます。
サンプルプログラム実行中に「z」か「Z」をターミナルで入力すると、CPU例外番号「14」の「Data Address (Write)」が引き起こされる仕掛けになっています。
この設定は「..\arch\avr32uc3_gcc\prc_test.h」の以下の記述で設定されています。
- ...
- #define CPUEXC1 14 /* Data Address (Write) */
- #define RAISE_CPU_EXCEPTION *(volatile int*)(0x1) = 0x11;
- ...
すなわち「CPUEXC1」に「14(Data Address (Write))」を定義し、サンプルプログラムから「RAISE_CPU_EXCEPTION」というマクロを呼び出すと「*(volatile int*)(0x1) = 0x11」という非常に行儀の悪いコードが実行されるようになっています。
(「0x1」という奇数番地を32ビットのポインターのアドレスとして扱い、更に、それに対して値を書き込んでいる!)
このイタズラにより、データを書き込むメモリのアドレスのアラインメントの不正が検出され、その名の通りの「14(Data Address (Write))」CPU例外が引き起こされます。
小文字の「z」と大文字の「Z」の違いは、CPU例外が小文字の場合はカーネル管轄内で、大文字の場合はカーネル管轄外でそれぞれ実行されるということだけです。
各CPU例外の詳細については、AVR32のデータシートを熟読していただく必要がありますが、これらが引き起こされた時点で致命的な状況が多く「4(NMI)」以外は、デバッグでの用途以外、あまり使い道はないでしょう。
●一部サービスコールは未対応
割り込みIDを指定して、これを有効/無効化するための「ena_int()」と「dis_int()」サービスコールはサポートしていません。
これはAVR32に搭載されている割り込みコントローラーがシンプルな設計であり、割り込み要因ごとに有効/無効化するためのフラグを設けていないためです。
どうしても一時的に割り込みを有効/無効化したい場合は、各ペリフェラルのレジスタを設定するか、CPU全体の割り込みを一括で設定しても良いのであれば、以下のような関数を呼び出すことで代用してください。
なお、以下の関数を使用するためには、これを使用するソースに「#include <avr32/io.h>」を一行加えてあげてください。
- Disable_global_interrupt(); /* すべての割込みの禁止 */
- Enable_global_interrupt(); /* すべての割込みの許可 */
また、性能評価用システム時刻取得のための「get_utm()」サービスコールは未実装です。
ライセンスについて
このカーネルは「TOPPERSライセンス」で配布しております。
無償ですが、使用に関しては自己責任です。
万が一、このカーネルを商用利用する方は、このリンク先の条項に従ってください…って、いらっしゃる訳ないですよね。
シリーズ自体がディスコンですから!
さて、絶滅危惧っていうか、ほぼ絶滅したアーキテクチャであるAVR32を取り上げてみました。
OS書き易かったし、良いマイコンなんだけどなぁ…。
強そうな「AVR32ロボ」(?)
でも市場で負けちゃった…。
(頭の形状から「おやおやおや…」とか言いそう。)
この可哀想なAVR32、TOPPERSカーネルもしばらくは頑張ってメンテナンスしていきますので、市場にある内にどうか使ってやって下さい!
<終わり>
0 件のコメント:
コメントを投稿