システム状態管理機能は、システムの状態を変更/参照するための機能である。タスクの優先順位を回転する機能、実行状態のタスクIDを参照する機能、タスクディスパッチを禁止/解除する機能、コンテキストやシステム状態を参照する機能、省電力モードを設定する機能、カーネルのバージョンを参照する機能が含まれる。
tskpri
で指定される優先度のタスクの優先順位を回転する。すなわち、対象優先度を持った実行できる状態のタスクの中で、最も高い優先順位を持つタスクを、同じ優先度を持つタスクの中で最低の優先順位とする。
tskpri
=TPRI_RUN=0により、その時実行状態(RUNNING)にあるタスクの優先度のタスクの優先順位を回転する。一般のタスクから発行される tk_rot_rdq では、これは自タスクの持つ優先度のタスクの優先順位を回転するのと同じ意味であるが、周期ハンドラなどのタスク独立部から tk_rot_rdq(tskpri
=TPRI_RUN) を発行することも可能である。
対象優先度を持った実行できる状態のタスクがない場合や、一つしかない場合には、何もしない(エラーとはしない)。
ディスパッチ許可状態で、対象優先度に TPRI_RUN または自タスクの現在優先度を指定してこのシステムコールが呼び出されると、自タスクの実行順位は同じ優先度を持つタスクの中で最低となる。そのため、このシステムコールを用いて、実行権の放棄を行うことができる。
ディスパッチ禁止状態では、同じ優先度を持つタスクの中で最高の優先順位を持ったタスクが実行されているとは限らないため、この方法で自タスクの実行順位が同じ優先度を持つタスクの中で最低となるとは限らない。
tk_rot_rdq の実行例を[図5], [図6]に示す。[図5]の状態で、tskpri
=2をパラメータとしてこのシステムコールが呼ばれると、新しい優先順位は[図6]のようになり、次に実行されるのはタスクCとなる。
なし
なし
tk_get_tid で返されるタスクIDは、tk_ref_sys で返される runtskid
と同一である。
なし
タスクのディスパッチを禁止する。これ以後 tk_ena_dsp が実行されるまでの間はディスパッチ禁止状態となり、自タスクが実行状態(RUNNING)から実行可能状態(READY)に移ることはなくなる。また、待ち状態に移ることもできなくなる。ただし、外部割込みは禁止しないので、ディスパッチ禁止状態であっても割込みハンドラは起動される。ディスパッチ禁止状態においては、実行中のタスクが割込みハンドラによってプリエンプト(CPUの実行権の横取り)される可能性はあるが、他のタスクによってプリエンプトされる可能性はない。
ディスパッチ禁止状態の間は、具体的には次のような動作をする。
割込みハンドラあるいは tk_dis_dsp を実行したタスクから発行されたシステムコールによって、tk_dis_dsp を実行したタスクより高い優先度を持つタスクが実行可能状態(READY)となっても、そのタスクにはディスパッチされない。優先度の高いタスクへのディスパッチは、ディスパッチ禁止状態が終了するまで遅延される。
tk_dis_dsp を実行したタスクが、自タスクを待ち状態に移す可能性のあるシステムコール(tk_slp_tsk、tk_wai_sem など) を発行した場合には、E_CTX のエラーとなる。
tk_ref_sys によってシステム状態を参照した場合、sysstat
として TSS_DDSP が返る。
既にディスパッチ禁止状態にあるタスクが tk_dis_dsp を発行した場合は、ディスパッチ禁止状態がそのまま継続するだけで、エラーとはならない。ただし、tk_dis_dsp を何回か発行しても、その後 tk_ena_dsp を1回発行するだけでディスパッチ禁止状態が解除される。したがって、tk_dis_dsp~tk_ena_dsp の対がネストした場合の動作は、必要に応じてユーザ側で管理しなければならない。
ディスパッチ禁止状態では、実行状態のタスクが休止状態(DORMANT)や未登録状態(NON-EXISTENT)に移行することはできない。割込みおよびディスパッチ禁止状態で、実行状態のタスクが tk_ext_tsk または tk_exd_tsk を発行した場合には、E_CTX のエラーを検出する。ただし、tk_ext_tsk や tk_exd_tsk は元のコンテキストに戻らないシステムコールなので、これらのシステムコールのリターンパラメータとしてエラーを通知することはできない。
なし
タスクのディスパッチを許可する。すなわち、tk_dis_dsp によって設定されていたディスパッチ禁止状態を解除する。
ディスパッチ禁止状態ではないタスクが tk_ena_dsp を発行した場合は、ディスパッチを許可した状態がそのまま継続するだけで、エラーとはならない。
pk_rsys
の内容
実行状態を参照し、ディスパッチ禁止中、タスク独立部実行中などといった情報をリターンパラメータとして返す。
sysstat
は次のような値をとる。
sysstat := ( TSS_TSK | [TSS_DDSP] | [TSS_DINT] ) || ( TSS_QTSK | [TSS_DDSP] | [TSS_DINT] ) || ( TSS_INDP )
runtskid
には現在実行中のタスクのID、schedtskid
には実行状態にすべきタスクのIDが返される。通常は runtskid
=schedtskid
となるが、ディスパッチ禁止中により優先度の高いタスクが起床された場合などに runtskid
≠schedtskid
となる場合がある。なお、該当タスクがない場合は0を返す。
割込みハンドラやタイムイベントハンドラからも発行できなければならない。
tk_ref_sys で返される情報は、カーネルの実装によっては、必ずしも常に正しい情報を返すとは限らない。
省電力機能は、次の2つの機能からなる。
実行すべきタスクがない状態のとき、ハードウェアに用意されている低消費電力モードに切り替える。
低消費電力モードは、タイマ割込みから次のタイマ割込みの間のようにごく短い時間の電力消費を抑えるための機能で、CPUのクロック周波数を下げることなどにより行われる。したがって、ソフトウェアによる複雑なモード切替を必要とせず、主にハードウェアの機能によって実現される。
オペレータが何も操作しない状態が一定時間以上続いた場合、自動的に電源を切りサスペンド状態に移行する。周辺機器からの起動要求(割込みなど)またはオペレータが電源を入れることによりリジュームされ、電源が切れたときの状態に復帰する。
また、バッテリー切れなどの電源異常によっても、自動的に電源を切りサスペンド状態に移行する。
サスペンド中は、周辺機器や周辺回路およびCPUの電源が切れる。しかし、メインメモリの内容は保持される。
tk_set_pow は、省電力モードの設定を行う。
powmode:= ( TPW_DOSUSPEND || TPW_DISLOWPOW || TPW_ENALOWPOW )
#define TPW_DOSUSPEND 1 サスペンド状態へ移行 #define TPW_DISLOWPOW 2 低消費電力モード切替禁止 #define TPW_ENALOWPOW 3 低消費電力モード切替許可(デフォルト)
TPW_DOSUSPEND
すべてのタスク及びハンドラの実行を停止し、周辺回路(タイマや割込みコントローラ)を停止し、電源を切る(サスペンドする)。(off_pow を呼び出す)
電源オンされたら、周辺回路の再起動をし、すべてのタスク及びハンドラの実行を再開して、電源を切る前の状態に復帰(リジューム)し、リターンする。
何らかの理由によりリジュームに失敗したときには、通常(リセット時)のスタートアップ処理を行い、新たにシステムを立ち上げなおす。
TPW_DISLOWPOW
ディスパッチャ内で行われる低消費電力モードへの切替を禁止する。(low_pow を呼び出さない)
TPW_ENALOWPOW
ディスパッチャ内で行われる低消費電力モードへの切替を許可する。(low_pow を呼び出す)
起動時のデフォルトは切替許可(TPW_ENALOWPOW)となる。
TPW_DISLOWPOW が指定された場合、その要求回数がカウントされる。TPW_DISLOWPOW が要求された回数と同じだけ TPW_ENALOWPOW が要求されないと、低消費電力モードは許可されない。要求カウント数の最大値は実装定義だが、少なくとも255回以上カウントできなければならない。
off_pow, low_pow はμT-Kernel/SMの機能である。詳細は 省電力機能項μT-Kernel/SMの機能章 を参照のこと。
μT-Kernelでは、電源異常などのサスペンド移行要因の検出は行わない。また、実際にサスペンドするためには、各周辺機器(デバイスドライバ)のサスペンド処理も必要である。サスペンドするには tk_set_pow を直接呼び出すのではなく、μT-Kernel/SMのサスペンド機能を利用する。
pk_rver
の内容
使用しているカーネルのバージョン情報を参照し、pk_rver
で指定されるパケットに返す。具体的には、次の情報を参照することができる。
maker
は、このカーネルを実装したμT-Kernel提供者のコードである。maker
のフォーマットを[図7]に示す。
prid
は、カーネルの種類を区別するための番号である。prid
のフォーマットを[図8]に示す。
prid
の具体的な値の割付けは、カーネルを実装したμT-Kernel提供者に任される。ただし、製品の区別はあくまでもこの番号のみで行うので、各μT-Kernel提供者において番号の付け方を十分に検討した上、体系づけて使用するようにしなければならない。したがって、 maker
と prid
の組でカーネルの種類を一意に識別することができる。
μT-Kernelのリファレンスコードは、トロンフォーラムから提供され、その maker
と prid
は次のようになる。
maker = 0x0000 prid = 0x0000
spver
では、上位4ビットでOS仕様の種類と、下位12ビットでカーネルが準拠する仕様のバージョン番号を表す。spver
のフォーマットを[図9]に示す。
たとえばμT-Kernelの Ver 3.01.xx の仕様書に対応する spver
は次のようになる。
MAGIC = 0x6 (μT-Kernel) SpecVer = 0x301 (Ver 3.01) spver = 0x6301
また、μT-Kernel仕様書のドラフト版であるVer 3.B0.xxの仕様書に対応する spver
は次のようになる。
MAGIC = 0x6 (μT-Kernel) SpecVer = 0x3B0 (Ver 3.B0) spver = 0x63B0
OS仕様の種類
カーネルが準拠する仕様のバージョン番号。3桁のパックト形式BCDコードで入れる。ドラフトの仕様書の場合は、上から2桁目がA, B, Cとなる場合もある。この場合は、対応する16進数のA, B, Cを入れる。
prver
は、カーネル実装上のバージョン番号を表す。prver
の具体的な値の割付けは、カーネルを実装したT-Kernel提供者に任される。
prno
は、カーネル製品の管理情報や製品番号などを入れるために使用するためのリターンパラメータである。prno
の具体的な値の意味は、カーネルを実装したT-Kernel提供者に任される。
バージョン情報を得るためのパケットの形式や構造体の各メンバのフォーマットの仕様は、T-KernelやμT-Kernelの各バージョンの間でほぼ共通になっている。
tk_ref_ver の SpecVer として得られるのは仕様書のバージョン番号の上位3桁であるが、これより下位の桁はミスプリントの修正などといった表記上の変更を表す桁なので、tk_ref_ver で得られる情報には含めていない。仕様書の内容との対応という意味では、仕様書のバージョン番号の上位3桁を知ることで必要十分である。
ドラフト版の仕様書を対象として実装されたカーネルでは、SpecVer の2桁目がA, B, Cとなることがある。この場合、仕様書のリリース順序と SpecVer の大小関係が必ずしも一致しないので、注意が必要である。仕様書のリリース順は、たとえばVer 2.A1→Ver 2.A2→Ver 2.B1→Ver 2.C1→Ver 2.00→Ver 2.01→... となるが、SpecVer の大小関係はドラフト版から正式版に移る部分(Ver 2.Cx→Ver 2.00の部分)で逆転する。