Cortex-M3 まとめ
少し前にCortex-M3のエミュレータを作った際にメモしておいたことを以下にまとめてみる。
コードアドレスのLSBについて
- 例外ベクタのLSBは例外が Thumb で実行されるかどうかを示すため、例外ベクタのLSBは1とする必要がある
- PCを変更するときは、上記の理由でLSBを1にする必要がある
- LDR でコードアドレスをロードした時も LSB に 1 がセットされる
LDR R0, =label ; R0 set to 0xXXX1
Exception について
- 割り込みがアサートされると割り込み保留状態となる
- SETPEND(0xE000E200) で保留状態を表示
- 書き込んで保留させることも可能。
- CPU が割り込みハンドラを開始すると、
- 保留状態がクリアされる
- アクティブステータスレジスタ(0xE000E300、読み出し専用)の対応ビットが1になる
- ハンドラを退出するまで同じ割り込みをネストしない(優先度が同じため)
- 保留はクリアレジスタ(0xE000E280)で任意にクリアも可能
- 割り込みハンドラを退出すると、
- アクティブステータスレジスタの対応ビットはクリアされる
- FAULTMASK が有効の場合、クリアされる
- 各割り込みはSETPEND(0xE000E200)とSTIR(0xE000EF00)で保留させることが出来る
- 内部の割り込みもPENDXX(0xE000ED04)で可能
- 保留可能な割り込みはNMI、PendSV、SysTick
PendSV について
- 一言で言えば、OS(特権) から ソフトウェア割り込みを保留するためのもの
- 割り込みハンドラ中に遅延させたい処理(コンテキストスイッチ)等がある場合に使用する
- SVC 例外は保留されないが、PendSVは保留される
- PENDSVSET を 1 に設定すると PendSV 要因が保留される
Priority について
- 8bit で定義
- 値が小さい方が高い
- -3(reset)、-2(NMI)、-1(ハードフォールト) は固定
- 8bit は NVIC の Application Interrupt/Reset Control (0xE000ED0C) の PRIGROUP により2分割される
- 横取り優先度レベル
- サブ優先度レベル
- 横取り優先度レベルは、割り込み発生時の優先度の判断に使われる
- 高い優先度が発生したら横取りされる
- 同じ優先度が発生したら無視される
- サブ優先度レベルは、同じ横取り優先度レベルが発生したとき、横取りするための値
- 同じ横取り優先度レベルで、サブ優先度が高ければ横取り