オリジナルOS「MicrOS」の設計と実装(3) ―― MicrOSのシステム・コール
1.MicrOSの導入
● アプリケーションごとに修正が必要なファイル
MicrOSは構造が単純で小さなOSなので,機能そのものの変更も可能です.処理内容を変更せずに利用する場合の導入方法を説明します.
MicrOSをアプリケーション・システムに組み込む前に行わなければならない作業があります.それは,次のソース・コードまたは関数の修正作業です.
- MicrOS.h,MicrOSasm.inc
- aplMain関数
- タイマ処理関数
- MicrOScmd.c
aplMain関数とタイマ処理関数については,そのテンプレートがMicrOS.cの先頭にあります.これをアプリケーションのソースにコピーして使用します.最小限MicrOS.hとMicrOSasm.hのカスタマイズが必要になります.
aplMain関数はMicrOSがマルチプログラミング制御に入る前に1回だけ呼ばれる関数です.タスク登録はaplMain関数の中で__task関数を使って行います.この関数以外の部分で__task関数をコールしてはいけません(MicrOSはこのチェックを行わない.この関数以外の部分でタスク関数をコールしたとき,メモリ・アロケーションやタスクの動作に異常が発生し,それがシステム全体に伝播して,アプリケーション・システムは破滅的な動作を行う).
● タイマをこまめに停止して動作する
タイマ処理関数はハードウェアの違いを吸収するための関数です.MicrOSのインターバル・タイマの制御は,省電力を図るためにできるだけタイマ割り込みを少なくしています.また,インターバル・タイマを使わないときはタイマをストップさせるというのが基本です.このような制御を行うためには,ハードウェアによって途中の経過時間を読み取る機能がサポートされていなければなりません.このような機能を持たないハードウェアであった場合には,定周期割り込みを発生させ,その割り込みをカウントする方法をとります.このときも,インターバル・タイマを使用しないならハードウェア・タイマをストップさせます.MicrOSのタイマ制御にはこの二つの処理がテンプレートとして組み込まれています.V850のタイマには,途中のタイマ・カウントを読み取る機能を持ったインターバル・タイマとカウントを読み取れないタイマがあり,2種類のタイマによる両方の機能がテンプレートとして組み込まれています.このどちらを使用するかは,MicrOS.hの中に定義されているSYSCLK_READ_OKで選択できます.
MicroOScmd.cにはUARTによるコマンド処理が組み込まれています.不要なコマンドを削除し,必要なコマンドを追加します.
アプリケーション・タスクの構造を簡単に示すと,リスト1のようになります.
/*========================================================+
| Application Task |
+=========================================================*/
int appTask_Template(void)
{
/*** internal valiables ***/
内部変数の定義
/*** initialize for this task ***/
ここでタスクが動作するときの初期設定を行う.
メールボックスとイベント・フラグはここで定義することで
このタスクがオーナとなる.タイマRQBなどは__rqbinitにより
ここで初期設定しておく.
また,タイマRQBをメモリ・ブロックから取得するときなど,
そのメモリ・ブロックをここで定義すれば,そのメモリ・ブ
ロックのオーナはこのタスクとなる.
while(1){
/*** call wait_system_call ***/
タスクの主要な処理は永久ループの中に組み込む.
普通は永久ループの先頭はウェイト系のシステム・
コールから始まる
}
return(0); /* not reach */
このリターン命令にコントロールは来ないはず
}
リスト1 アプリケーション・タスクの構造
● システム・コールの返り値
MicrOSのシステム・コールは,返り値に関して三つのタイプに分かれます.
- 返り値を持たないもの
- ポインタ型
- 整数型
ポインタ型は一つのポインタを返り値とします.この関数の返り値がNULLのときは,要求が不成功に終わったことを示します.このタイプの場合,0xffffffffと0xfffffffe,0x0fffffffdがエラー・コードの拡張用として予約されています.
整数型は一つの整数値を返り値とします.正値および0は正常処理されたことを意味します.負値は,処理が正常に終了しなかったことを意味します.
この原則はおおむね当てはまりますが,負値がエラーでないこともありえます(現状では,イベント制御でそのようなイベントが定義されたときだけ).
代表的なエラー・コードを表2に示します.
エラー・コード | 数値 | 説 明 |
E_OK | 0 | 正常終了 |
E_NOWAIT | -8 | タスクはウェイトしていない |
E_WAITFLAG | -9 | ウェイト・フラグが不当 |
E_STACK | -10 | スタック・オーバフロー |
E_NOTRQB | -11 | RQBでない |
E_NOTSCB | -12 | SCBでない |
E_TIMERLINK | -13 | タイマ・リンクが存在していない |
E_PARAM | -14 | 要求パラメータにエラーがある |
E_MEMORY | -15 | メモリが不足している |
E_WAITSTS | -16 | ウェイト・ステータスがエラー |
E_WAITLINK | -17 | SCBウェイト・リンクのエラー |
E_PRI | -18 | 優先度エラー |
E_TMOVR | -19 | タイム・オーバ途中で終了 |
E_CANTCAN | -20 | キャンセルできない |
E_CANTMR | -21 | タイマ・キャンセル |
E_FLASH | -23 | フラッシュ・アクセス・エラー |
tag: OS