クレア工房 | 電子工作 | PIC32

PIC32の割り込み

x86 CPUの割り込みが比較的単純な構造を持っているのに対し、 MIPS CPUの割り込みは厄介な代物です。 なにせ当初なにも存在しないところに、屋上屋の拡張を足しているのです。 文書上の記述も分散しており、とても難解で複雑です。 正直な感想としては、ハードウェア実装量を省くためとはいえ、 結果的にかなり汚い設計をしてしまったもんだなと思います。

PIC32MXはMIPS用語でいうところのEICを搭載し、常時EICで動作します。

原則

割り込みの動作モード

ブートモード

リセット直後においては、プロセッサはブートモードで起動します。 ブートモードの中において、 非ブートモードで使用するべき必要なレジスタを初期化します。 具体的にはEBaseレジスタなどをブートモードにおいて初期化します。

割り込み アドレス 記事
Reset Error 0xBFC0_0000
NMI Error 0xBFC0_0000
TLB Miss Exception 0xBFC0_0200 歴史的な参考
Cache Error 0xBFC0_0300 歴史的な参考
General Exception 0xBFC0_0380
  • Interrupt at CauseIV = 0
  • Machine Check
  • Watch Exception
  • Address Error
  • Bus Error
  • System Call
Interrupt Exception 0xBFC0_0400 Interrupt at CauseIV = 1
Debug Exception 0xBFC0_0480 without EJTAG probe
Debug Exception 0xFF20_0200 with EJTAG probe

通常モード

EBaseレジスタを運用するモードです。 EBaseレジスタは一部のビットがハードコードされており、 任意のアドレスを指定することはできません。

割り込み アドレス 記事
Reset Error 0xBFC0_0000
NMI Error 0xBFC0_0000
TLB Miss Exception 0x8000_0000 歴史的な参考です。 EBaseレジスタが初期化されている場合はEBaseレジスタに従います。
Cache Error 0xA000_0100 歴史的な参考です。 EBaseレジスタが初期化されている場合はEBaseレジスタに従いますが MIPS CPUがキャッシュを禁じたアドレスレンジに固定されるという特殊なルールがあります。 具体的にはbit29が強制的に立ちます。
General Exception 0x8000_0180 EBaseレジスタが初期化されている場合はEBaseレジスタに従います。 具体的には(EBase + 0x180)に飛び込んできます。
  • Interrupt at CauseIV = 0
  • Machine Check
  • Watch Exception
  • Address Error
  • Bus Error
  • System Call
Interrupt Exception 0x8000_0200 Interrupt at CauseIV = 1 のときに使われます。 (EBase + 0x200) と定義されるのでEBaseレジスタを設定して移動することができます。 割り込み先となるアドレスの間隔は指定でき、IntCtlレジスタを操作して対応します。
Debug Exception 0xBFC0_0480 without EJTAG probe trapping
Debug Exception 0xFF20_0200 with EJTAG probe trapping

PIC32MX2xxにはTLB機構がないため、 割り込みベクタ領域の先頭0x180バイトは未使用領域ということになるかと思います。 RAMは貴重なので、相対的に余裕があるROMを割り当てたほうが良いでしょう。

モード切り替え

コプロセッサ0にあるSTATUSレジスタを操作します。

先に述べたとおり、プロセッサはリセット直後においてブートモードに初期化された状態で起動します。 初期化ルーチンはBEVビットを寝かしてからmain関数を呼び出すべきでしょう。

EBaseレジスタ

EBaseレジスタはexception baseという名前が示すとおり 例外発生時の基底となるアドレスを指すポインタです。 EBaseレジスタは一部のビットしか実装されていません。 下位12bitは実体が存在しないため、 下位12bitがゼロに整列されなければなりません。 このため、メモリマップを考える上では、 割り込みベクタの配置先となるアドレスの候補は限定されます。

シングルベクタ

PIC32MXはEICで運用されるので、 コアタイマを含めて一般的なハードウェア割り込みについて MIPS CPU固有のアドレスルールは適用されません。 シングルベクタはEICが割り込み番号ゼロを強制することで実現されます。 常に0x8000_0200に飛び込んでくると考えればよいでしょう。 このアドレスはEBaseレジスタを設定することで移動することができます。

マルチベクタ

マルチベクタはEICのレジスタを操作することで実現します。 PIC32MX2xxではオフセットを指定するレジスタは実装されないため、 計算モードを使うしかありません。 IntCtlレジスタのvector spacingビット群を指定することで 割り込みエントリポイントの間隔を指定できます。 PIC32MX2xxのデータシートによれば44本のベクタが存在します。 ざっくり電卓を叩いてみると、 最低限度となる32バイトのスペーシングを適用した場合で1920バイトほど消費する計算になります。 x86の常識ではベクタテーブルにはデスクリプタまたはポインタが並びますが、 MIPSの常識ではベクタテーブルにはプログラムコード本体が埋め込まれます。 32バイトの場合は割り込みルーチン全体を収容することはまずできませんので、 無条件分岐命令だけが配置されることになるでしょう。

シャドウレジスタ

MIPS CPUは設計時の選択においてシャドウレジスタセットを持つことができます。 PIC32MX2xxではデータシートにおいてシャドウレジスタの記載がありません。 とりあえずシャドウレジスタはないものとして実装しておき、 制御レジスタを読んでみてシャドウレジスタが存在する様子であれば シャドウレジスタを初期化して使ってみても良いでしょう。

割り込みに関連して初期化が必要なレジスタは2つあります。


This is copyrighted material. all rights reserved.