第3章 タスク管理機能
RI850V4におけるタスク管理機能では,タスクの生成/起動/終了などといったタスクの状態を操作する機能のほかに,優先度の参照,タスク詳細情報の参照などといったタスクの状態を参照する機能も提供しています。
なお,RI850V4では,タスクを管理するに当たり,タスクと一対一に対応した管理オブジェクト(タスク管理ブロック)を用いることにより,タスクが取り得る状態の管理,およびタスク自体の管理を行っています。
備考 タスクが処理を実行するうえで必要となるプログラム・カウンタ,汎用レジスタなどの実行環境情報は,“タスク・コンテキスト”と呼ばれ,タスクの実行が切り替わる際には,現在実行中のタスクのタスク・コンテキストがセーブされ,次に実行されるタスクのタスク・コンテキストがロードされます。
タスクは,処理を実行するうえで必要となる資源の獲得状況,および事象発生の有無などにより,さまざまな状態へと遷移していきます。そこで,RI850V4では,各タスクが現在どのような状態にあるかを認識し,管理する必要があります。
タスクとして起動されていない状態,またはタスクとしての処理を終了した際に遷移する状態です。
なお,DORMANT状態のタスクは,RI850V4の管理下にありながらも,RI850V4のスケジューリング対象からは除外されています。
なお,DORMANT状態のタスクは,RI850V4の管理下にありながらも,RI850V4のスケジューリング対象からは除外されています。
処理を実行するうえで必要となる条件が整わないため,処理の実行が中断した状態です。
なお,WAITING状態からの処理再開は,処理の実行が中断した箇所からとなります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキスト:プログラム・カウンタ,汎用レジスタなど)は,中断直前の値が復元されます。
また,RI850V4では,要求条件の種類により,WAITING状態を以下に示す10状態に細分化し,管理しています。
なお,WAITING状態からの処理再開は,処理の実行が中断した箇所からとなります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキスト:プログラム・カウンタ,汎用レジスタなど)は,中断直前の値が復元されます。
また,RI850V4では,要求条件の種類により,WAITING状態を以下に示す10状態に細分化し,管理しています。
強制的に処理の実行を中断させられた状態です。
なお,SUSPENDED状態からの処理再開は,処理の実行が中断した箇所からの再開となります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキスト:プログラム・カウンタ,汎用レジスタなど)は,中断直前の値が復元されます。
なお,SUSPENDED状態からの処理再開は,処理の実行が中断した箇所からの再開となります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキスト:プログラム・カウンタ,汎用レジスタなど)は,中断直前の値が復元されます。
WAITING状態とSUSPENDED状態が複合した状態です。
なお,WAITING状態が解除された際にはSUSPENDED状態へ,SUSPENDED状態が解除された際にはWAITING状態へと遷移します。
なお,WAITING状態が解除された際にはSUSPENDED状態へ,SUSPENDED状態が解除された際にはWAITING状態へと遷移します。
タスクには,処理を実行するうえでの優先順位を決定する優先度が付けられています。そこで,RI850V4のスケジューラでは,実行可能な状態(RUNNING状態,およびREADY状態)にあるタスクの優先度を参照し,その中から最も高い優先度(最高優先度)を持つタスクを選び出し,CPUの利用権を与えています。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ............ ............ ext_tsk ( ); /*タスクの終了*/ } |
備考1 sta_tsk,またはista_tskの発行によりDORMANT状態からREADY状態へと遷移した場合,引き数exinfには“sta_tsk,またはista_tsk発行時に指定した拡張情報”が設定されます。
- 記述方法
C言語,またはアセンブリ言語で記述します。
C言語で記述するときは通常の関数と同様に記述することができます。
アセンブリ言語で記述するときは使用するコンパイラの呼び出し規約にのっとって作成してください。
C言語,またはアセンブリ言語で記述します。
C言語で記述するときは通常の関数と同様に記述することができます。
アセンブリ言語で記述するときは使用するコンパイラの呼び出し規約にのっとって作成してください。
- スタックの切り替え
RI850V4では,タスクを切り替える際,タスク情報において指定されたタスク・スタックへの切り替え処理を行っています。したがって,タスク内でスタックの切り替えに関する記述を行う必要がありません。
RI850V4では,タスクを切り替える際,タスク情報において指定されたタスク・スタックへの切り替え処理を行っています。したがって,タスク内でスタックの切り替えに関する記述を行う必要がありません。
- EIレベル・マスカブル割り込みの受け付け状態
RI850V4では,タスクを起動する際,プライオリティ・マスク・レジスタPMRのPMnビットに対する操作,およびプログラム・ステータス・ワードPSWのIDビットに対する操作を行い,システム・コンフィギュレーション作成時に属性(記述言語,初期起動状態など)tskatrで指定された割り込み状態としています。
RI850V4では,タスクを起動する際,プライオリティ・マスク・レジスタPMRのPMnビットに対する操作,およびプログラム・ステータス・ワードPSWのIDビットに対する操作を行い,システム・コンフィギュレーション作成時に属性(記述言語,初期起動状態など)tskatrで指定された割り込み状態としています。
なお,RI850V4では,コンフィギュレーション時にタスク情報で指定した拡張情報,およびサービス・コールsta_tsk,ista_tsk発行時に第2パラメータstacdで指定した値を“タスクの拡張情報”と呼んでいます。
- act_tsk,iact_tsk
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させたのち,初期優先度itskpriに応じたレディ・キューの最後尾にキューイングします。これにより,対象タスクは,RI850V4のスケジューリング対象となります。
ただし,本サービス・コールを発行した際,対象タスクがDORMANT状態以外の場合には,対象タスクのキューイング処理,および状態操作処理は行わず,対象タスクに起動要求をキューイング(起動要求カウンタに0x1を加算)しています。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させたのち,初期優先度itskpriに応じたレディ・キューの最後尾にキューイングします。これにより,対象タスクは,RI850V4のスケジューリング対象となります。
ただし,本サービス・コールを発行した際,対象タスクがDORMANT状態以外の場合には,対象タスクのキューイング処理,および状態操作処理は行わず,対象タスクに起動要求をキューイング(起動要求カウンタに0x1を加算)しています。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ID tskid = ID_TSK1; /*変数の宣言,初期化*/ ............ ............ act_tsk ( tskid ); /*タスクの起動(起動要求をキューイングする)*/ ............ ............ } |
備考1 RI850V4が管理する起動要求カウンタは,7ビット幅で構成されています。このため,本サービス・コールでは,起動要求数が127回を越えるような場合には,起動要求の発行起動要求のキューイング(起動要求カウンタの加算処理)は行わず,戻り値としてE_QOVRを返します。
- sta_tsk,ista_tsk
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させたのち,初期優先度itskpriに応じたレディ・キューの最後尾にキューイングします。これにより,対象タスクは,RI850V4のスケジューリング対象となります。
ただし,本サービス・コールでは,起動要求のキューイングが行われません。このため,対象タスクがDORMANT状態以外の場合には,対象タスクの状態操作処理は行わず,戻り値としてE_OBJを返します。
なお,パラメータstacdには,対象タスクに引き渡す拡張情報を指定します。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させたのち,初期優先度itskpriに応じたレディ・キューの最後尾にキューイングします。これにより,対象タスクは,RI850V4のスケジューリング対象となります。
ただし,本サービス・コールでは,起動要求のキューイングが行われません。このため,対象タスクがDORMANT状態以外の場合には,対象タスクの状態操作処理は行わず,戻り値としてE_OBJを返します。
なお,パラメータstacdには,対象タスクに引き渡す拡張情報を指定します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ID tskid = ID_TSK1; /*変数の宣言,初期化*/ VP_INT stacd = 123; /*変数の宣言,初期化*/ ............ ............ sta_tsk ( tskid, stacd ); /*タスクの起動(起動要求をキューイングしない)*/ ............ ............ } |
- can_act,ican_act
パラメータtskidで指定されたタスクにキューイングされている起動要求をすべて解除(起動要求カウンタに0x0を設定)します。
なお,正常終了時は戻り値として本サービス・コールの発行により解除した起動要求数を返します。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクにキューイングされている起動要求をすべて解除(起動要求カウンタに0x0を設定)します。
なお,正常終了時は戻り値として本サービス・コールの発行により解除した起動要求数を返します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ER_UINT ercd; /*変数の宣言*/ ID tskid = ID_TSK1; /*変数の宣言,初期化*/ ............ ............ ercd = can_act ( tskid ); /*起動要求のキューイング解除*/ if ( ercd >= 0x0 ) { ............ /*正常終了処理*/ ............ } ............ ............ } |
- ext_tsk
自タスクをRUNNING状態からDORMANT状態へと遷移させ,レディ・キューから外します。これにより,自タスクは,RI850V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,自タスクの起動要求がキューイングされていた(起動要求カウンタが0x0以外の値であった)場合には,自タスクの状態操作(DORMANT状態への状態遷移処理)を行ったのち,自タスクの起動(DORMANT状態からREADY状態への状態遷移処理)もあわせて行われます。
以下に,本サービス・コールの記述例を示します。
自タスクをRUNNING状態からDORMANT状態へと遷移させ,レディ・キューから外します。これにより,自タスクは,RI850V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,自タスクの起動要求がキューイングされていた(起動要求カウンタが0x0以外の値であった)場合には,自タスクの状態操作(DORMANT状態への状態遷移処理)を行ったのち,自タスクの起動(DORMANT状態からREADY状態への状態遷移処理)もあわせて行われます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ............ ............ ext_tsk ( ); /*タスクの終了*/ } |
- ter_tsk
パラメータtskidで指定されたタスクを強制的にDORMANT状態へと遷移させます。これにより,対象タスクは,RI850V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,対象タスクの起動要求がキューイングされていた(起動要求カウンタが0x0以外の値であった)場合には,対象タスクの状態操作(DORMANT状態への状態遷移処理)を行ったのち,対象タスクの起動(DORMANT状態からREADY状態への状態遷移処理)もあわせて行われます。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクを強制的にDORMANT状態へと遷移させます。これにより,対象タスクは,RI850V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,対象タスクの起動要求がキューイングされていた(起動要求カウンタが0x0以外の値であった)場合には,対象タスクの状態操作(DORMANT状態への状態遷移処理)を行ったのち,対象タスクの起動(DORMANT状態からREADY状態への状態遷移処理)もあわせて行われます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ID tskid = ID_TSK1; /*変数の宣言,初期化*/ ............ ............ ter_tsk ( tskid ); /*タスクの強制終了*/ ............ ............ } |
- chg_pri,ichg_pri
パラメータtskidで指定されたタスクの優先度(現在優先度)をパラメータtskpriで指定された値に変更します。
対象タスクがRUNNING状態,またはREADY状態であった場合には,優先度を変更したのち,対象タスクをパラメータtskpriで指定された優先度に応じたレディ・キューの最後尾につなぎかえます。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクの優先度(現在優先度)をパラメータtskpriで指定された値に変更します。
対象タスクがRUNNING状態,またはREADY状態であった場合には,優先度を変更したのち,対象タスクをパラメータtskpriで指定された優先度に応じたレディ・キューの最後尾につなぎかえます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ID tskid = ID_TSK1; /*変数の宣言,初期化*/ PRI tskpri = 9; /*変数の宣言,初期化*/ ............ ............ chg_pri ( tskid, tskpri ); /*タスク優先度の変更*/ ............ ............ } |
例 セマフォの待ちキューに3つのタスク(タスクA:優先度10,タスクB:優先度11,タスクC:優先度12)が優先度順でキューイングされているとき,タスクBの優先度を11から9に変更した場合,待ちキューの待ち順序は,以下のように変更されます。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ID tskid = ID_TSK1; /*変数の宣言,初期化*/ PRI p_tskpri; /*変数の宣言*/ ............ ............ get_pri ( tskid, &p_tskpri ); /*タスク優先度の参照*/ ............ ............ } |
- ref_tsk,iref_tsk
パラメータtskidで指定されたタスクのタスク詳細情報(現在状態,現在優先度など)をパラメータpk_rtskで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクのタスク詳細情報(現在状態,現在優先度など)をパラメータpk_rtskで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ID tskid = ID_TSK1; /*変数の宣言,初期化*/ T_RTSK pk_rtsk; /*データ構造体の宣言*/ STAT tskstat; /*変数の宣言*/ PRI tskpri; /*変数の宣言*/ STAT tskwait; /*変数の宣言*/ ID wobjid; /*変数の宣言*/ TMO lefttmo; /*変数の宣言*/ UINT actcnt; /*変数の宣言*/ UINT wupcnt; /*変数の宣言*/ UINT suscnt; /*変数の宣言*/ ATR tskatr; /*変数の宣言*/ PRI itskpri; /*変数の宣言*/ ............ ............ ref_tsk ( tskid, &pk_rtsk ); /*タスク詳細情報の参照*/ tskstat = pk_rtsk.tskstat; /*現在状態の獲得*/ tskpri = pk_rtsk.tskpri; /*現在優先度の獲得*/ tskwait = pk_rtsk.tskwait; /*待ち要因の獲得*/ wobjid = pk_rtsk.wobjid; /*管理オブジェクトのIDの獲得*/ lefttmo = pk_rtsk.lefttmo; /*残り時間の獲得*/ actcnt = pk_rtsk.actcnt; /*起動要求数の獲得*/ wupcnt = pk_rtsk.wupcnt; /*起床要求数の獲得*/ suscnt = pk_rtsk.suscnt; /*サスペンド要求数の獲得*/ tskatr = pk_rtsk.tskatr; /*属性の獲得*/ itskpri = pk_rtsk.itskpri; /*初期優先度の獲得*/ ............ ............ } |
- ref_tst,iref_tst
パラメータtskidで指定されたタスクのタスク基本情報(現在状態,待ち要因)をパラメータpk_rtstで指定された領域に格納します。
タスク情報のうち,現在状態,待ち要因のみを参照したい場合に使用します。
取得する情報が少ないのでref_tsk,iref_tskより高速に応答します。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクのタスク基本情報(現在状態,待ち要因)をパラメータpk_rtstで指定された領域に格納します。
タスク情報のうち,現在状態,待ち要因のみを参照したい場合に使用します。
取得する情報が少ないのでref_tsk,iref_tskより高速に応答します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void task ( VP_INT exinf ) { ID tskid = ID_TSK1; /*変数の宣言,初期化*/ T_RTST pk_rtst; /*データ構造体の宣言*/ STAT tskstat; /*変数の宣言*/ STAT tskwait; /*変数の宣言*/ ............ ............ ref_tst ( tskid, &pk_rtst ); /*タスク基本情報の参照*/ tskstat = pk_rtst.tskstat; /*現在状態の獲得*/ tskwait = pk_rtst.tskwait; /*待ち要因の獲得*/ ............ ............ } |