この章では、μT-Kernel/OS(Operating System)で提供しているシステムコールの詳細について説明を行う。
タスク管理機能は、タスクの状態を直接的に操作/参照するための機能である。タスクを生成/削除する機能、タスクを起動/終了する機能、タスクの優先度を変更する機能、タスクの状態を参照する機能が含まれる。タスクはID番号で識別されるオブジェクトである。タスクのID番号をタスクIDと呼ぶ。タスク状態とスケジューリング規則については、タスク状態とスケジューリング規則項μT-Kernelの概念章を参照すること。
タスクは、実行順序を制御するために、ベース優先度と現在優先度を持つ。単にタスクの優先度といった場合には、タスクの現在優先度を指す。タスクのベース優先度は、タスクの起動時にタスクの起動時優先度に初期化する。ミューテックス機能を使わない場合には、タスクの現在優先度は常にベース優先度に一致している。そのため、タスク起動直後の現在優先度は、タスクの起動時優先度になっている。ミューテックス機能を使う場合に現在優先度がどのように設定されるかについては、ミューテックス項で述べる。
カーネルは、タスクの終了時に、ミューテックスのロック解除を除いては、タスクが獲得した資源(セマフォ資源、メモリブロックなど)を解放する処理を行わない。タスク終了時に資源を解放するのは、アプリケーションの責任である。
pk_ctsk
の内容
void* |
exinf
| Extended Information | 拡張情報 |
ATR |
tskatr
| Task Attribute | タスク属性 |
FP |
task
| Task Start Address | タスク起動アドレス |
PRI |
itskpri
| Initial Task Priority | タスク起動時優先度 |
SZ |
stksz
| Stack Size | スタックサイズ(バイト数) |
SZ |
sstksz
| System Stack Size | システムスタックサイズ(バイト数) |
void* |
stkptr
| User Stack Pointer | ユーザスタックポインタ |
UB |
dsname[8]
| DS Object name | DSオブジェクト名称 |
void* |
bufptr
| Buffer Pointer | ユーザバッファポインタ |
──(以下に実装独自に他の情報を追加してもよい)── |
TK_SUPPORT_ASM | TA_ASMのタスク属性指定が可能 |
TK_SUPPORT_USERBUF | TA_USERBUFのタスク属性指定が可能 |
TK_SUPPORT_AUTOBUF | 自動バッファ割当て(TA_USERBUFのタスク属性指定なし)が可能 |
TK_SUPPORT_FPU | TA_FPUのタスク属性指定が可能 |
TK_SUPPORT_COPn | TA_COPnのタスク属性指定が可能 |
TK_HAS_SYSSTACK | タスクがユーザスタックとは独立したシステムスタックを持ち、ユーザスタック・システムスタックに対する個別の指定(TA_USERSTACK, TA_SSTKSZ)が可能 |
TK_SUPPORT_DSNAME | TA_DSNAMEのタスク属性指定が可能 |
TK_MAX_TSKPRI | 指定可能な最大タスク優先度の値 (>= 16) |
タスクを生成しタスクID番号を割り当てる。具体的には、生成するタスクに対してTCB(Task Control Block)を割り付け、itskpri
, task
, stksz
などの情報をもとにその初期設定を行う。
対象タスクは生成後、休止状態(DORMANT)となる。
itskpri
によって、タスクが起動する時の優先度の初期値を指定する。タスク優先度には1以上の値を指定することができ、数の小さい方が高い優先度となる。指定可能な最大のタスク優先度は TK_MAX_TSKPRI で規定される。
exinf
は、対象タスクに関する情報を入れておくためにユーザが自由に利用できる。ここで設定した情報は、タスクに起動パラメータとして渡される他、tk_ref_tsk で取り出すことができる。なお、ユーザの情報を入れるためにもっと大きな領域がほしい場合や、途中で内容を変更したい場合には、自分でそのためのメモリを確保し、そのメモリパケットのアドレスを exinf
に入れる。カーネルでは exinf
の内容について関知しない。
tskatr
は、下位側がシステム属性を表し、上位側が実装独自属性を表す。tskatr
のシステム属性の部分では、次のような指定を行う。
tskatr := (TA_ASM || TA_HLNG) | [TA_SSTKSZ] | [TA_USERSTACK] | [TA_USERBUF] | [TA_DSNAME] | (TA_RNG0 || TA_RNG1 || TA_RNG2 || TA_RNG3) | [TA_COP0] | [TA_COP1] | [TA_COP2] | [TA_COP3] | [TA_FPU]
TA_ASM | 対象タスクがアセンブリ言語で書かれている |
TA_HLNG | 対象タスクが高級言語で書かれている |
TA_SSTKSZ | システムスタックサイズを指定する |
TA_USERSTACK | ユーザスタックポインタを指定する |
TA_USERBUF | スタック領域としてユーザが指定した領域を使用する |
TA_DSNAME | DSオブジェクト名称を指定する |
TA_RNGn | 対象タスクは保護レベルnで実行する |
TA_COPn | 対象タスクが第n番目のコプロセッサを使用する(浮動小数点演算用コプロセッサやDSPを含む) |
TA_FPU | 対象タスクが浮動小数点演算用コプロセッサを使用する(TA_COPn による指定の内、特に浮動小数点演算を使用するための、CPUに依存しない汎用的な指定である) |
実装独自属性の機能は、例えば、被デバッグ対象のタスクであることを指定したりするために利用できる。また、システム属性の残りの部分は、将来マルチプロセッサ属性の指定などを行うために利用できる。
#define TA_ASM 0x00000000 /* アセンブリ言語によるプログラム */ #define TA_HLNG 0x00000001 /* 高級言語によるプログラム */ #define TA_SSTKSZ 0x00000002 /* システムスタックサイズを指定 */ #define TA_USERSTACK 0x00000004 /* ユーザスタックポインタを指定 */ #define TA_USERBUF 0x00000020 /* ユーザバッファポインタを指定 */ #define TA_DSNAME 0x00000040 /* DSオブジェクト名称を指定 */ #define TA_RNG0 0x00000000 /* 保護レベル0 で実行 */ #define TA_RNG1 0x00000100 /* 保護レベル1 で実行 */ #define TA_RNG2 0x00000200 /* 保護レベル2 で実行 */ #define TA_RNG3 0x00000300 /* 保護レベル3 で実行 */ #define TA_COP0 0x00001000 /* ID=0 のコプロセッサを使用 */ #define TA_COP1 0x00002000 /* ID=1 のコプロセッサを使用 */ #define TA_COP2 0x00004000 /* ID=2 のコプロセッサを使用 */ #define TA_COP3 0x00008000 /* ID=3 のコプロセッサを使用 */
TA_HLNG の指定を行った場合には、タスク起動時に直接 task
のアドレスにジャンプするのではなく、高級言語の環境設定プログラム(高級言語対応ルーチン)を通してから task
のアドレスにジャンプする。TA_HLNG 属性の場合のタスクは次の形式となる。
void task( INT stacd, void *exinf ) { /* 処理 */ tk_ext_tsk(); または tk_exd_tsk(); /* タスクの終了 */ }
タスクの起動パラメータとして、tk_sta_tsk で指定するタスク起動コード stacd
、および tk_cre_tsk で指定する拡張情報 exinf
を渡す。
関数からの単純なリターン(return)でタスクを終了することはできない(してはいけない)。その場合の動作は不定(実装依存)である。
TA_ASM 属性の場合のタスクの形式は実装依存とする。ただし、起動パラメータとして stacd
, exinf
を渡さなければならない。
タスクは、TA_RNGn で指定された保護レベルで動作する。システムコールや拡張SVCを呼び出すことで保護レベル0に移行し、システムコールや拡張SVCから戻ると元の保護レベルに復帰する。
各タスクはシステムスタックとユーザスタックの2本のスタックを持つ。ユーザスタックは TA_RNGn で指定した保護レベルで使用される。システムスタックは保護レベル0で使用される。システムコールや拡張SVCを呼び出すことにより保護レベルが遷移したときに使用するスタックが切り替えられる。
なお、TA_RNG0 を指定したタスクでは、保護レベルの遷移が起きないためスタックの切替も起きない。TA_RNG0 の場合は、ユーザスタックサイズとシステムスタックサイズの合計を1本のスタックとし、ユーザスタック兼システムスタックとして使用する。
TA_SSTKSZ を指定した場合に sstksz
が有効になる。TA_SSTKSZ を指定しなかった場合は、sstksz
は無視されデフォルトサイズが適用される。
TA_USERSTACK を指定した場合に stkptr
が有効になる。この場合、ユーザスタックはカーネルで用意しない。ユーザスタックは呼出側で用意する。stksz
には0を設定しなければならない。TA_USERSTACK を指定しなかった場合は、stkptr
は無視される。ただし、TA_RNG0 の場合は、TA_USERSTACK を指定することはできない。TA_RNG0 と TA_USERSTACK を同時に指定した場合は E_PAR が発生する。
ユーザスタックとシステムスタックを区別せずタスクごとにスタックを1本持った実装向けに TA_USERBUF の指定が提供される。この属性を指定した場合に bufptr
が有効となり、bufptr
を先頭とする stksz
バイトのメモリ領域をユーザスタック兼システムスタック領域として使用する。この場合、これらのスタックはカーネルで用意しない。
TA_DSNAME を指定した場合に dsname
が有効となり、DSオブジェクト名称として設定される。DSオブジェクト名称はデバッガがオブジェクトを識別するために使用され、T-Kernel/DSのシステムコール td_ref_dsname と td_set_dsname からのみ操作可能である。詳細は td_ref_dsname 、td_set_dsname を参照のこと。TA_DSNAME を指定しなかった場合は、dsname
が無視され、td_ref_dsname や td_set_dsname が、E_OBJ エラーとなる。
タスクは、TA_RNGn で指定した保護レベルと保護レベル0のいずれかでのみ動作する。例えば、TA_RNG3 を指定したタスクが保護レベル1および2で動作することはない。
割込みスタックが分離されていないシステムでは、割込みハンドラもシステムスタックを使用する。割込みハンドラは保護レベル0で動作する。
システムスタックのデフォルトサイズは、システムコールの実行により消費するサイズおよび割込みスタックが分離されていないシステムでは割込みハンドラにより消費されるサイズを考慮して決定する。
TA_COPn の定義は、CPUなどのハードウェアに依存して決められるため移植性はない。
TA_FPU は、TA_COPn の定義の内、浮動小数点演算の使用に関してのみ移植性のある指定方法として用意される。例えば、浮動小数点コプロセッサが TA_COP0 の場合は、TA_FPU=TA_COP0 となる。浮動小数点演算を行うのに特にコプロセッサの使用を指定する必要がない場合は、TA_FPU=0となる。
CPUの実行保護モードのないシステムにおいても、移植性確保のために TA_RNGn などすべての属性を受け付けなければならない。例えば、TA_RNGn の指定はすべて TA_RNG0 相当として処理してもよいが、エラーとはしない。
T-Kernel 2.0にはTA_USERBUFとbufptr
が存在しない。そのため、この機能を使っている場合はT-Kernel 2.0への移植の際に修正が必要となるが、正しくstksz
を設定してあれば、TA_USERBUFとbufptr
を削除するだけで移植できる。
μT-Kernelの最大のタスク優先度はTK_MAX_TSKPRIで示される。この値は可変だが、16以上であることが保証されているため、利用するタスク優先度の範囲を1〜16に限定することで移植の際のタスク優先度の修正が不要となる。
tskid
で示されたタスクを削除する。
具体的には、tskid
で指定されたタスクを休止状態(DORMANT)から未登録状態(NON-EXISTENT)(システムに存在しない状態)へと移行させ、それに伴ってTCBおよびスタック領域を解放する。また、タスクID番号も解放される。休止状態(DORMANT)でないタスクに対してこのシステムコールを実行すると、E_OBJ のエラーとなる。
このシステムコールで自タスクの指定はできない。自タスクを指定した場合には、自タスクが休止状態(DORMANT)ではないため、E_OBJ のエラーとなる。自タスクを削除するには、本システムコールではなく、tk_exd_tsk システムコールを発行する。
tskid
で示されたタスクを起動する。具体的には、休止状態(DORMANT)から実行可能状態(READY)へと移す。
stacd
により、タスクの起動時にタスクに渡すパラメータを設定することができる。このパラメータは、対象タスクから参照することができ、簡単なメッセージ通信の目的で利用できる。
タスク起動時のタスク優先度は、対象タスクが生成された時に指定されたタスク起動時優先度(itskpri
)となる。
このシステムコールによる起動要求のキューイングは行わない。すなわち、対象タスクが休止状態(DORMANT)でないのにこのシステムコールが発行された場合、このシステムコールは無視され、発行タスクに E_OBJ のエラーが返る。
stacd
がINT型であり、処理系によって指定できる値の範囲が異なる可能性があるため注意が必要である。
なし
※ システムコールを発行したコンテキストには戻らない
※ 次のようなエラーを検出する可能性があるが、エラーを検出した場合でも、システムコールを発行したコンテキストには戻らない。したがって、システムコールのリターンパラメータとして直接エラーコードを返すことはできない。万一エラーを検出した場合の動作は、実装依存となる。
自タスクを正常終了させ、休止状態(DORMANT)へと移行させる。
tk_ext_tsk によるタスクの終了時に、終了するタスクがそれ以前に獲得した資源(メモリブロック、セマフォなど) を自動的に解放するということはない。タスク終了前に資源を解放しておくのは、ユーザの責任である。
tk_ext_tsk は発行元のコンテキストに戻らないシステムコールである。したがって、何らかのエラーを検出した場合にエラーコードを返しても、これらのシステムコールを呼んだ側ではエラーのチェックを行っていないのが普通であり、プログラムが暴走する可能性がある。そこで、これらのシステムコールでは、エラーを検出した場合にも、システムコール発行元へは戻らないものとする。
タスクが休止状態(DORMANT)に戻る時は、タスク優先度などTCBに含まれている情報もリセットされるというのが原則である。たとえば、tk_chg_pri によりタスク優先度を変更されているタスクが、tk_ext_tsk により終了した時、タスク優先度は tk_cre_tsk で指定したタスク起動時優先度(itskpri
)に戻る。tk_ext_tsk 実行時のタスク優先度になるわけではない。
元のコンテキストに戻らないシステムコールは、すべてtk_ret_???またはtk_ext_???(tk_exd_???)の名称となっている。
なし
※ システムコールを発行したコンテキストには戻らない
※ 次のようなエラーを検出する可能性があるが、エラーを検出した場合でも、システムコールを発行したコンテキストには戻らない。したがって、システムコールのリターンパラメータとして直接エラーコードを返すことはできない。万一エラーを検出した場合の動作は、実装依存となる。
自タスクを正常終了させ、さらに自タスクを削除する。すなわち、自タスクを未登録状態(NON-EXISTENT)(システムに存在しない状態)へと移行させる。
tk_exd_tsk によるタスクの終了時に、終了するタスクがそれ以前に獲得した資源(メモリブロック、セマフォなど) を自動的に解放するということはない。タスク終了前に資源を解放しておくのは、ユーザの責任である。
tk_exd_tsk は発行元のコンテキストに戻らないシステムコールである。したがって、何らかのエラーを検出した場合にエラーコードを返しても、これらのシステムコールを呼んだ側ではエラーのチェックを行っていないのが普通であり、プログラムが暴走する可能性がある。そこで、これらのシステムコールでは、エラーを検出した場合にも、システムコール発行元へは戻らないものとする。
tskid
で示されたタスクを強制的に終了させる。すなわち、tskid
で示された対象タスクを休止状態(DORMANT)に移行させる。
対象タスクが待ち状態(強制待ち状態(SUSPENDED)を含む)にあった場合でも、対象タスクは待ち解除となって終了する。また、対象タスクが何らかの待ち行列(セマフォ待ちなど)につながれていた場合には、tk_ter_tsk の実行によってその待ち行列から削除される。
本システムコールでは、自タスクの指定はできない。自タスクを指定した場合には、E_OBJ のエラーとなる。
tk_ter_tsk の対象タスクの状態と実行結果との関係についてまとめたものを表1に示す。
表 1. tk_ter_tskの対象タスクの状態と実行結果
対象タスク状態 | tk_ter_tsk の ercd | 処理 |
---|---|---|
実行できる状態(RUNNING,READY) (自タスク以外) | E_OK | 強制終了処理 |
実行状態(RUNNING)(自タスク) | E_OBJ | 何もしない |
待ち状態(WAITING) | E_OK | 強制終了処理 |
強制待ち状態(SUSPENDED) | E_OK | 強制終了処理 |
二重待ち状態(WAITING-SUSPENDED) | E_OK | 強制終了処理 |
休止状態(DORMANT) | E_OBJ | 何もしない |
未登録状態(NON-EXISTENT) | E_NOEXS | 何もしない |
tk_ter_tsk によるタスクの終了時に、終了するタスクがそれ以前に獲得した資源(メモリブロック、セマフォなど)を自動的に解放するということはない。タスク終了前に資源を解放しておくのは、ユーザの責任である。
タスクが休止状態(DORMANT)に戻る時は、タスク優先度などTCBに含まれている情報もリセットされるというのが原則である。たとえば、tk_chg_pri によりタスク優先度を変更されているタスクが、tk_ter_tsk により終了した時、タスク優先度は tk_cre_tsk で指定したタスク起動時優先度(itskpri
)に戻る。tk_sta_tsk によって再度タスクを起動した場合、tk_ter_tsk を実行して強制終了された時のタスク優先度になるわけではない。
他タスクの強制終了は、デバッガなどのOSに密接に関連したごく一部でのみ使用することを原則とする。一般のアプリケーションやミドルウェアでは、他タスクの強制終了は原則として使用してはいけない。これは次のような理由による。
強制終了は、対象タスクの実行状態に関係なく行われる。例えば、タスクがあるミドルウェアの機能を呼び出しているとき、そのタスクを強制終了するとミドルウェアの実行途中でタスクが終了してしまうことになる。そのような状況になれば、ミドルウェアの正常動作は保証できなくなる。
このように、タスクの状態(何を実行中か)が不明な状況で、そのタスクを強制終了させることはできない。したがって、一般にタスクの強制終了は使用してはならない。
tskid
で指定されるタスクのベース優先度を、tskpri
で指定される値に変更する。それに伴って、タスクの現在優先度も変更する。
タスク優先度としては、1~TK_MAX_TSKPRIの値を指定することができ、数の小さい方が高い優先度となる。
tskid
に TSK_SELF(=0)が指定されると、自タスクを対象タスクとする。ただし、タスク独立部から発行したシステムコールで tskid
=TSK_SELF を指定した場合には、E_ID のエラーとなる。また、tskpri
に TPRI_INI(=0)が指定されると、対象タスクのベース優先度を、タスクの起動時優先度(itskpri
)に変更する。
このシステムコールで変更した優先度は、タスクが終了するまで有効である。タスクが休止状態(DORMANT)に戻る時、終了前のタスクの優先度は捨てられ、タスク生成時に指定されたタスク起動時優先度(itskpri
)になる。ただし、休止状態(DORMANT)中に変更した優先度は有効である。次にタスクを起動したときは、その変更された優先度で起動される。
このシステムコールを実行した結果、対象タスクの現在優先度がベース優先度に一致している場合(ミューテックス機能を使わない場合には、この条件は常に成り立つ)には、次の処理を行う。
対象タスクが実行できる状態である場合、タスクの優先順位を、変更後の優先度にしたがって変化させる。変更後の優先度と同じ優先度を持つタスクの間では、対象タスクの優先順位を最低とする。
対象タスクが何らかのタスク優先度順の待ち行列につながれている場合にも、その待ち行列の中での順序を、変更後の優先度にしたがって変化させる。変更後の優先度と同じ優先度を持つタスクの間では、対象タスクを最後につなぐ。
対象タスクが TA_CEILING 属性のミューテックスをロックしているか、ロックを待っている場合で、tskpri
で指定されたベース優先度が、それらのミューテックスのいずれかの上限優先度よりも高い場合には、E_ILUSE エラーを返す。
このシステムコールを呼び出した結果、対象タスクのタスク優先度順の待ち行列の中での順序が変化した場合、対象タスクないしはその待ち行列で待っている他のタスクの待ち解除が必要になる場合がある(メッセージバッファの送信待ち行列、および可変長メモリプールの獲得待ち行列)。
対象タスクが、TA_INHERIT 属性のミューテックスのロック待ち状態である場合、このシステムコールでベース優先度を変更したことにより、推移的な優先度継承の処理が必要になる場合がある。
ミューテックス機能を使わない場合には、対象タスクに自タスク、変更後の優先度に自タスクのベース優先度を指定してこのシステムコールが呼び出されると、自タスクの実行順位は同じ優先度を持つタスクの中で最低となる。そのため、このシステムコールを用いて、実行権の放棄を行うことができる。
μT-Kernelの最大のタスク優先度はTK_MAX_TSKPRIで示される。この値は可変だが、16以上であることが保証されているため、利用するタスク優先度の範囲を1〜16に限定することで移植の際のタスク優先度の修正が不要となる。
tskid
のタスクの現在のレジスタの内容を参照する。
pk_regs
, pk_eit
, pk_cregs
にそれぞれ NULL を指定すると、対応するレジスタは参照されない。
参照されたレジスタの値が、タスク部実行中のものであるとは限らない。
自タスクに対して本システムコールを発行することはできない。(E_OBJ)
参照可能なレジスタは、タスクのコンテキストに含まれるすべてのレジスタを原則とする。また、CPUに物理的に存在するレジスタ以外に、カーネルが仮想的にレジスタとして扱っているものがあればそれも含まれる。
ID |
tskid
| Task ID | 対象タスクのID |
CONST T_REGS* |
pk_regs
| Packet of Registers | 汎用レジスタ |
CONST T_EIT* |
pk_eit
| Packet of EIT Registers | 例外時に保存されるレジスタ |
CONST T_CREGS* |
pk_cregs
| Packet of Control Registers | 制御レジスタ |
T_REGS, T_EIT, T_CREGSの内容は、CPUおよび実装ごとに定義する。
tskid
のタスクのレジスタを指定の内容に設定する。
pk_regs
, pk_eit
, pk_cregs
にそれぞれ NULL を指定すると、対応するレジスタは設定されない。
設定するレジスタの値が、タスク部実行中のものであるとは限らない。レジスタの値を設定したことによる影響には、カーネルは関知しない。
ただし、カーネルの動作上変更が許されないレジスタやレジスタ内の一部のビットが変更できないようになっている場合がある。(実装依存)
自タスクに対して本システムコールを発行することはできない。(E_OBJ)
pk_copregs
の内容
T_COP0REG |
cop0
| Coprocessor Number 0 Register | コプロセッサ番号0のレジスタ |
T_COP1REG |
cop1
| Coprocessor Number 1 Register | コプロセッサ番号1のレジスタ |
T_COP2REG |
cop2
| Coprocessor Number 2 Register | コプロセッサ番号2のレジスタ |
T_COP3REG |
cop3
| Coprocessor Number 3 Register | コプロセッサ番号3のレジスタ |
T_COPnREGの内容は、CPUおよび実装ごとに定義する。
なお、すべてのn
についてTK_SUPPORT_COPnが無効である場合、本APIはサポートされない。
tskid
のタスクの copno
で指定したコプロセッサの現在のレジスタ内容を参照する。
参照されたレジスタの値が、タスク部実行中のものであるとは限らない。
自タスクに対して本システムコールを発行することはできない。(E_OBJ)
参照可能なレジスタは、タスクのコンテキストに含まれるすべてのレジスタを原則とする。また、CPUに物理的に存在するレジスタ以外に、カーネルが仮想的にレジスタとして扱っているものがあればそれも含まれる。
ID |
tskid
| Task ID | 対象タスクのID |
INT |
copno
| Coprocessor Number | コプロセッサ番号(0~3) |
CONST T_COPREGS* |
pk_copregs
| Packet of Coprocessor Registers | コプロセッサのレジスタ |
pk_copregs
の内容
なお、すべてのn
についてTK_SUPPORT_COPnが無効である場合、本APIはサポートされない。
tskid
のタスクの copno
で指定したコプロセッサのレジスタに指定の内容を設定する。
設定するレジスタの値が、タスク部実行中のものであるとは限らない。レジスタの値を設定したことによる影響には、カーネルは関知しない。
ただし、カーネルの動作上変更が許されないレジスタやレジスタ内の一部のビットが変更できないようになっている場合がある。(実装依存)
自タスクに対して本システムコールを発行することはできない。(E_OBJ)
pk_rtsk
の内容
void* |
exinf
| Extended Information | 拡張情報 |
PRI |
tskpri
| Task Priority | 現在の優先度 |
PRI |
tskbpri
| Task Base Priority | ベース優先度 |
UINT |
tskstat
| Task State | タスク状態 |
UW |
tskwait
| Task Wait Factor | 待ち要因 |
ID |
wid
| Waiting Object ID | 待ちオブジェクトID |
INT |
wupcnt
| Wakeup Count | 起床要求キューイング数 |
INT |
suscnt
| Suspend Count | 強制待ち要求ネスト数 |
UW |
waitmask
| Wait Mask | 待ちを禁止されている待ち要因 |
UINT |
texmask
| Task Exception Mask | 許可されているタスク例外 |
UINT |
tskevent
| Task Event | 発生しているタスクイベント |
──(以下に実装独自に他の情報を追加してもよい)── |
tskid
で示された対象タスクの各種の状態を参照する。
tskstat
は次のような値をとる。
TTS_RUN | 0x0001 | 実行状態(RUNNING) |
TTS_RDY | 0x0002 | 実行可能状態(READY) |
TTS_WAI | 0x0004 | 待ち状態(WAITING) |
TTS_SUS | 0x0008 | 強制待ち状態(SUSPENDED) |
TTS_WAS | 0x000c | 二重待ち状態(WAITING-SUSPENDED) |
TTS_DMT | 0x0010 | 休止状態(DORMANT) |
TTS_NODISWAI | 0x0080 | 待ち禁止拒否状態 |
TTS_RUN, TTS_WAI などによるタスク状態の表現はビット対応になっているため、和集合の判定を行う(例えば、実行状態(RUNNING)または実行可能状態(READY)であることを判定する)場合に便利である。なお、上記の状態のうち、TTS_WAS は TTS_SUS と TTS_WAI が複合したものであるが、TTS_SUS がこれ以外の状態(TTS_RUN, TTS_RDY, TTS_DMT)と複合することはない。
TTS_WAI(TTS_WAS 含む)の場合、tk_dis_wai による待ち禁止を拒否している状態であれば、TTS_NODISWAI がセットされる。TTS_WAI 以外と TTS_NODISWAI が組み合わされることはない。
割込みハンドラの中から、割り込まれたタスクを対象とした tk_ref_tsk を実行した場合は、tskstat
として実行状態(RUNNING)(TTS_RUN)を返す。
tskstat
が TTS_WAI(TTS_WAS を含む)の場合、tskwait
, wid
は 表2のような値をとる。
表 2. tskwait
と wid
の値
tskwait
| 値 | 意味 |
wid
|
---|---|---|---|
TTW_SLP | 0x00000001 | tk_slp_tsk による待ち | 0 |
TTW_DLY | 0x00000002 | tk_dly_tsk による待ち | 0 |
TTW_SEM | 0x00000004 | tk_wai_sem による待ち | 待ち対象の semid |
TTW_FLG | 0x00000008 | tk_wai_flg による待ち | 待ち対象の flgid |
TTW_MBX | 0x00000040 | tk_rcv_mbx による待ち | 待ち対象の mbxid |
TTW_MTX | 0x00000080 | tk_loc_mtx による待ち | 待ち対象の mtxid |
TTW_SMBF | 0x00000100 | tk_snd_mbf による待ち | 待ち対象の mbfid |
TTW_RMBF | 0x00000200 | tk_rcv_mbf による待ち | 待ち対象の mbfid |
TTW_CAL | 0x00000400 | (予約) | (予約) |
TTW_ACP | 0x00000800 | (予約) | (予約) |
TTW_RDV | 0x00001000 | (予約) | (予約) |
(TTW_CAL | TTW_RDV) | 0x00001400 | (予約) | (予約) |
TTW_MPF | 0x00002000 | tk_get_mpf による待ち | 待ち対象の mpfid |
TTW_MPL | 0x00004000 | tk_get_mpl による待ち | 待ち対象の mplid |
TTW_EV1 | 0x00010000 | タスクイベント#1待ち | 0 |
TTW_EV2 | 0x00020000 | タスクイベント#2待ち | 0 |
TTW_EV3 | 0x00040000 | タスクイベント#3待ち | 0 |
TTW_EV4 | 0x00080000 | タスクイベント#4待ち | 0 |
TTW_EV5 | 0x00100000 | タスクイベント#5待ち | 0 |
TTW_EV6 | 0x00200000 | タスクイベント#6待ち | 0 |
TTW_EV7 | 0x00400000 | タスクイベント#7待ち | 0 |
TTW_EV8 | 0x00800000 | タスクイベント#8待ち | 0 |
tskstat
が TTS_WAI (TTS_WAS を含む) でない場合は、tskwait
, wid
はともに0となる。
waitmask
は、tskwait
と同じビット並びとなる。
texmask
は、許可されている各タスク例外を1<<タスク例外コードのビット値として、論理和(OR)した値である。
tskevent
は、発生している各タスクイベントを1<<(タスクイベント番号-1)のビット値として論理和(OR)した値である。
休止状態(DORMANT)のタスクでは wupcnt
=0, suscnt
=0, tskevent
=0 である。
tskid
=TSK_SELF=0によって自タスクの指定を行うことができる。ただし、タスク独立部から発行したシステムコールで tskid
=TSK_SELF=0を指定した場合には、E_ID のエラーとなる。
tk_ref_tsk で、対象タスクが存在しない場合には、エラー E_NOEXS となる。
このシステムコールで tskid
=TSK_SELF を指定した場合でも、自タスクのIDは分からない。自タスクのIDを知りたい場合には、tk_get_tid を利用する。