割り込み処理について
この処理の概要及びそのために必要なものについて最低限説明する。
実際のコードの動きを追走しジャンプの動きを確認する
12ステップでできる組込みOS入門のコードを参考にし、実際の割り込みの動作を確認する。
アセンブリコードで大まかな一連の流れが確認できる。
PCとコントロールレジスタの保存、特権モードへの切り替えはハードウェア側で自動で行われるため割愛する。
rteは割り込み復帰命令である。割り込み復帰命令については後述する。
mov.w #SOFTVEC_TYPE_SERINTR, r0について
r0に対して#SOFTVEC_TYPE_SERINTRを代入する命令である。
そして、 r0,er1共に下の @_interruptに渡す引数である。
interruptの本体である関数は第一引数に割り込みの種類、第2引数にspを取る。
つまり、interruptは#SOFTVEC_TYPE_SERINTRとer1を引数として処理を実行する
void interrupt(softvec_type_t type, unsigned long sp)
{
softvec_handler_t handler = SOFTVECS[type];
if (handler)
handler(type, sp);
}
interruptの役割は、関数ハンドラの実行である。
handlerに対して割り込みベクタに設定されている関数ハンドラを代入し、handlerが取得できた場合、ハンドラを実行する様になっている。
今回、ハンドラとして登録されている関数はmainを見ると確認できる
int main(void)
{
INTR_DISABLE; //CCRの1ビットを上げる。CPUの割り込み処理を無効化
puts("kozos boot succeed!\n");
softvec_setintr(SOFTVEC_TYPE_SERINTR, intr);
serial_intr_recv_enable(SERIAL_DEFAULT_DEVICE);
puts("> ");
INTR_ENABLE;//CCRの1ビットを落とし。CPUの割り込み処理を有効化
while (1) {
asm volatile ("sleep");
}
return 0;
//このwhileループは通常、省電力モードでCPUの命令実行を停止させ、割り込みが発生することで動作します。これにより、割り込みドリブン(割り込み駆動) の仕組みを利用して、CPUの消費電力を制御しています。
}
softvec_setintr関数では、ハンドラとその種類を指定しており、具体的にはSOFTVEC_TYPE_SERINTRに対応するintr関数が今回実行されるハンドラ関数であることが理解できる。
実際のコードを追うことで、ジャンプがどのように処理され、ハンドラ関数がどのように実行されるのかがより理解できる。
割り込み復帰命令
ジャンプで関数を実行したあとは復旧を行う必要がある。
先述のアセンブリでは汎用レジスタの復旧のあと、 rteという割り込み復帰命令が行われていた。
これはこの本で使用されているH8マイコンの割り込み復帰命令である。この割り込み復帰命令では、PCとコントロールレジスタの値を復旧する。
以上を行うことで中断していた箇所から再開することができる。
まとめ
- 特権モードに切り替え、
- 現在のPC,コントロールレジスタの値を保存する
- 汎用レジスタの情報を保存する
- 割り込みハンドラのアドレスを取得し、PCを割り込みハンドラに書き換え実行する
- 保存した汎用レジスタを復旧する
- PCとコントロールレジスタの復旧
以上の流れで、割り込み処理を実行することができる。