オリジナルOS「MicrOS」の設計と実装(4) ―― リアルタイム性の確保
● MicrOSでのリアルタイム処理部分
各部分の処理はどの程度のステップ数になるのでしょうか.外部割り込み処理とディスパッチャの処理をMicrOSの場合で詳細に示します.
外部割り込み処理の流れをリスト1に示します(理想的なMicrOSの場合).次に,ディスパッチャの処理をリスト2に示します.
外部割り込み発生
(A)までの処理に必要なレジスタをスタックにセーブ(LRレジスタを含めて3~4)
if( OldPSWをチェック,割り込み処理中?){
そのほかのレジスタをスタックにセーブ
} else {
システム・コントロール・ブロックのカレントTCBを取得
if( 実行中タスクはあるか?){
SPレジスタをセーブ
TCBに残りのレジスタをセーブ
}
}
(A) 外部割り込みのPSW(OldPSW)とPC(OldPC)をバリアブル・レジスタにセーブ
割り込みコントローラから割り込みベクタ番号を取得し,
個別の割り込み処理をレジスタにロード
ei(多重割り込み処理のため)
個別の割り込み処理をコール
EOI処理
di(割り込みを再度禁止)
if( OldPSWは割り込み処理中?){
OldPSW,OldPCを外部割り込みに戻す
スタックからレジスタをリストア
reti
} else if( 実行中タスクあり?){
if( タスク・スイッチあり?)){
OldPSW,OldPCをTCBのPSWとPCにセット
Aまでの処理でスタックにセーブしたレジスタをTCBの所定の位置へ
TCBをレディ・プールへ登録
} else {
OldPSW,OldPCを外部割り込みに戻す
TCBからレジスタをリストア
Aまでの処理でスタックにセーブしたレジスタをスタックから戻す
reti
}
}
ディスパッチャへジャンプする
実行中タスクとタスク・アクティブ・フラグをクリアする
プライオリティ・テーブルの先頭,サーチするプライオリティ数をセット
for(i =0; i < SYSNPRI; i++){
if( PRITBLE[i] != (TCB*)0) break;
}
if( i < SYSNPRI){
di
TCBをレディ・プールから取り出して実行タスクにセット
TCBのPSW,PCを外部割り込み」のレジスタにセットする
TCBにセーブされているレジスタをリストア
reti →タスクの実行
}
halt
外部割り込み処理は多重割り込み処理を行うことを前提に,その処理を示しています.このときV850を前提にすると全体がつかみにくくなるので,割り込みコントローラはベクタ・ジャンプせずに,ベクタ番号を通知する前提でこの処理を記述してあります.
この処理をアセンブラで記述した場合,汎用レジスタ数が16程度であれば,外部割り込み処理は60ステップ前後,ディスパッチャの処理は30ステップというところでしょう.この中にスタック操作があるので,実行ステップとしてはそれぞれ80,50と見当を付けてよいと思います.V850であれば100,70というところでしょうか.
まず,割り込みが発生してからそれを受け付けるまでが最初のステップです.もし割り込みが発生しても受け付けられないとすれば,それは割り込み禁止状態になっているときです.割り込み禁止状態とは,外部割り込み処理を行っているときかシステム・コールの処理を行っているときです.
外部割り込み処理で割り込み禁止になっている部分では,割り込み発生からei(Enable Interrupt:割り込み許可)を発行するまでの処理が目に付きます.ここまでの処理で,割り込みが発生したときに実行中のタスクが存在していたときの処理量が多く,ここでおよそ全体の半分近くの処理時間になります
● システム・コールでの処理時間の見積もり
システム・コールですが,MicrOSではSCB(Service Control Block)を使う場合のみを対象とすればよいでしょう.タスクのプライオリティ順,メールのプライオリティ順を使わなければ,リンク処理の時間はほぼ固定しているので,アセンブラのステップ数が分かればその処理ステップ数は計算できます.厄介なのは,メモリ・アロケーションとインターバル・タイマのサービスです.これらのサービス機能の処理時間は,アプリケーションからどれだけの要求が発生するかによって変わってきます.
まずメモリ・アロケーションです.先頭のブロックで確保できなかった場合,それ以降で確保できる可能性は極端に低くなるので,ループ回数を制限すれば割り込み禁止時間を固定化でき,この機能を使わずにアプリケーション・システムを構成することも可能です.
インターバル・タイマの場合,ある瞬間を捉えたときにそこでタイマ要求が幾つあるかが問題になります.この要求数の最大の瞬間で,かつその最後に要求をリンクする処理を行う瞬間に,外部からクリティカルな要求が発生したときの遅れを計算しないといけません.しかし,これはMicrOS側ではパラメータを使って計算式を示すくらいのことしかできません.
システム・コールの割り込み禁止時間を計測する場合は,ウエイト系の処理を使ってシステム・コールの最初のdi(Disable Interrupt:割り込み禁止)からディスパッチャの入り口にあるeiまでを計測すればよいでしょう.
以上が,割り込み発生から割り込み受け付けまでの遅れの最大値です.