オリジナルOS「MicrOS」の設計と実装(1) ―― MicrOSの概要とソースの概観
イベント・フラグを更新するときに排他制御を行います.MicrOSがサービスのために行う排他制御は,割り込み禁止と割り込み解除の組み合わせです.
MicrOSでは,イベント・フラグのようにサービスを処理するために定義される構造体を総称してSCB(Service Control Block)といい,標準的な形式をリスト14のように定義しています.
リスト14 SCBの定義
typedef struct _SCB_T{ _RQB *head; /* next link */ _RQB *tail; /* prior link */ union{ struct{ unsigned char typ; /* type */ unsigned char pri; /* */ unsigned char sts; /* */ unsigned char prs; /* */ } s; unsigned int ui; } u; union{ /* task or procedure */ _TCB *tcb; int (*proc)(void); } p; } _SCB;
実はこの形式そのままの形で定義されるSCBはありません.この定義は平均的なもので,サービスの種類によっては欠けている情報もあり,それよりもたくさんの追加情報が定義されます.ただ,リンク情報を必要とするSCBにはheadとtailが,リンク方式を区別する必要があればtypがあり,このワードを形成するpri,sts,prsもあります.stsとprsが結び付いてHalfwordのデータを保持することもあります.MicrOSでは多くのシステム・コールがこのSCBのフォーマットに当てはまる形式で定義されます.特に,データのリンクが必要な場合はこれから外れることはありません.
SCBで使われるのは双方向リンクです.TCBの形式を参照してください.nextとpriorが定義されており,nextは次のTCBのポインタです.次がなければ0となります.priorはこのTCBを次とするTCBのポインタで,自分の直前にサービスを受けます.priorがないとき,それはSCBのポインタとなります.この双方向リンクはリンクの性格が変わっても必ず処理されています.これはキャンセル処理に強いリンクですが,アプリケーション・システムの要請によっては,キャンセル処理がどのような形で要求されるか不明であるため,時間的に安定したこのリンク方式を採用しています.
メールボックスのシステム・コールsnd_mbxは,SCBであるメールボックスのほかにメール・データを定義する構造体を持っています.サービスの主体であるSCBに対して,そのサービスを受ける形で定義されるこのような構造体をMicrOSはRQB(Request Block)と総称します.RQBはサービスの種類によって構造を変えます.この定義からすると,TCBもRQBの範ちゅうです.TCBはプライオリティ・テーブルにリンクされた状態がReady状態で,実行している状態がRun状態,これ以外の状態はWait状態となるので,プライオリティ・テーブル以外のSCBにリンクされている状態はWait状態となります.また,プライオリティ・テーブルはReadyタスクを管理する一種のSCBと見ることもできます.このような概念的なことはその時々に合わせて使い分ければ良く,それによってMicrOSを構成するプログラムが整理され,共通化して再利用が可能となります.リスト15にRQBの標準的な定義を示します.
リスト15 RQBの定義
typedef struct _RQB_T{ struct _RQB_T *next; /* next link */ struct _RQB_T *prior; /* prior link */ union{ struct _TCB_T *tcb; /* owner task TCB address */ struct{ unsigned char typ; /* */ unsigned char pri; /* */ unsigned char sts; /* */ unsigned char prs; /* */ } s; } u; unsigned int p0; /* Parameter1 */ unsigned int p1; /* Parameter2 */ unsigned int p2; /* Parameter3 */ unsigned int p3; /* Patameter4 */ } _RQB;
このRQBの定義を見ると,SCB,RQB,TCBの三つの構造体はすべて似ており,TCB以外はサービスによってその構造を変更しています.MicrOSのサービス処理を構成するときにはサービス主体とサービスの客体を意識して設計し,そこに作業用メモリが必要なときはTCBの構造をまねて設計すればプログラムの再利用が可能となります.結果として,組み込みOSなどが簡単に構成できます.そのためにSCB,RQBという言葉を定義しただけのことです.このような設計を行えば,使われない領域も生じますが,メモリ上の無駄が多少あっても,それを個別にプログラム(RAMとフラッシュROMの違いはあるが,プログラムもメモリに置かれる)するのに比べれば大したことはなく,プログラムにはデバッグという作業が伴うため同じような構造を採用する効果は明らかです.