(第37回)割り込みに優先度をつける(中編)

2009/01/23

あなたは 人目のお客様です.

割り込みの優先度づけ(割り込み優先度の導入)なのだけど,現状の extintr の作りが タイマとコンソールにべったりと張りついたかんじになっていて,このまま 優先度を導入すると,なんかぐちゃぐちゃになってしまいそう.

なので,準備としてちょっと extintr を整理しよう.

まず,子プロセスで行っている作業(割り込みコントローラの動作に相当する部分)は, extcont.c に移動する.あと,ライブラリ関数的なものは extsub.c に移動. で,KOZOSでの割り込み処理スレッド(extintrスレッド)の処理は extintr.c に残す.

これによりソケットまわりの処理は完全に extcont.c に切り離せることになる. もともとソケットを利用しているのは,子プロセスがシリアルコンソールの動作を telnet接続によって模擬しているためだ(KOZOSからは,ソケット通信なのかどうかは わからない).なのでソケットまわりをぜんぶ子プロセス処理(extcont.c)に 持っていって,KOZOSカーネルとは関係が無いようにしてしまうわけだ.

さらに割り込み優先度を設定するために,割り込みを一般化(抽象化)したものとして struct interrupts というクラスを作成する.まあちょっとクラスっぽくない部分も あってクラスと言うにはちょっと語弊があるのだけど,まああまり気にしない.

で,struct interrupts の配列として interrupts[] というのを用意して, タイマとコンソールの各割り込み(timerreg[] と consreg[])は,interrupts[] の 配列要素のどれかに対応するようにする. 現状でタイマ割り込みは4本,コンソール割り込みは4本あるので, interrupts[] は8個の要素を用意して,それぞれ対応させるようにする.

タイマとコンソールの各割り込みは struct timerreg と struct consreg で管理されて いるのだけど,これらはそのまま残す.というのは, 実際のハードウエア・プラットホームではハードウエアのレジスタ操作により タイマコントローラやシリアルコントローラを操作することになる. で,KOZOSではこれを子プロセスとのパイプ通信で模擬している. なので,レジスタ操作にかかわる部分(パイプ通信部分)はそのまま timerreg, consreg として残して,明確にしておきたいからだ.この部分はKOZOSを実ハードウエア上で 動かす際に,実際のハードウエアレジスタの操作に置き換えれば,そのまま動くことに なる.(実はもっとオブジェクト指向っぽくして,継承や多態性を使ってきれいに できるとも思うのだけど,そーいう理由であえてそうしない)

あとメッセージフォーマットとかをちょっと見直してみた. ソースは以下のような感じ.

(2009/04/10 ライセンスに関する文書として,KL-01とLICENSEを追加. 詳しくは第43回を参照)

いちおう,タイマとコンソールがきちんと動作することは確認した. extintr まわりを前回からわりとごっそり書き換えてしまったのだけど, まあやってることは変わっていないのでそれほどわかりにくくはないと思う.

割り込み優先度(まだ優先度は無いのだけど)を登録しているのは extintr.c:extintr_main() の以下のぶぶん.

  extintr_intr_regist(&interrupts[0], &timerreg[0], timer_init);
  extintr_intr_regist(&interrupts[1], & consreg[0],  cons_init);
  extintr_intr_regist(&interrupts[2], &timerreg[1], timer_init);
  extintr_intr_regist(&interrupts[3], & consreg[1],  cons_init);
  extintr_intr_regist(&interrupts[4], &timerreg[2], timer_init);
  extintr_intr_regist(&interrupts[5], & consreg[2],  cons_init);
  extintr_intr_regist(&interrupts[6], &timerreg[3], timer_init);
  extintr_intr_regist(&interrupts[7], & consreg[3],  cons_init);
たとえば上記1行目は,こーいうふうに読む.

「タイマ割り込みの0番を優先度0の割り込みとして登録し, timer_init()を呼び出して初期化する」

これにより,以下のように割り込みが登録される.

今回は優先度をつける準備として,ソースコードを整理しなおした. 次回は,いよいよ実際に優先度づけをしていこう.
メールは kozos(アットマーク)kozos.jp まで