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分割される
    • 横取り優先度レベル
    • サブ優先度レベル
  • 横取り優先度レベルは、割り込み発生時の優先度の判断に使われる
    • 高い優先度が発生したら横取りされる
    • 同じ優先度が発生したら無視される
  • サブ優先度レベルは、同じ横取り優先度レベルが発生したとき、横取りするための値
    • 同じ横取り優先度レベルで、サブ優先度が高ければ横取り