第3章 タスク管理機能
タスクは,他の処理プログラム(周期ハンドラ,割り込みハンドラなど)とは異なり,RI78V4が提供するサービス・コールを使用して明示的に操作しない限り実行されることのない処理プログラムであり,スケジューラから呼び出されます。
備考 タスクが処理を実行するうえで必要となる実行環境情報は,“タスク・コンテキスト”と呼ばれ,タスクの実行が切り替わる際には,RI78V4により現在実行中のタスクのタスク・コンテキストがセーブされ,次に実行されるタスクのタスク・コンテキストがロードされます。
タスクは,処理を実行するうえで必要となるOS資源の獲得状況,および,事象発生の有無などにより,様々な状態へと遷移していきます。そこで,RI78V4では,各タスクが現在どのような状態にあるかを認識し,管理する必要があります。
タスクとして起動されていない状態,またはタスクとしての処理を終了した際に遷移する状態です。
なお,DORMANT状態のタスクは,RI78V4の管理下にありながらも,RI78V4のスケジューリング対象からは除外されています。
なお,DORMANT状態のタスクは,RI78V4の管理下にありながらも,RI78V4のスケジューリング対象からは除外されています。
処理を実行するうえで必要となる条件が整わないため,処理の実行が中断した状態です。
なお,WAITING状態からの処理再開は,処理の実行が中断した箇所からとなります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキストなど)は,中断直前の値が復元されます。
また,RI78V4では,要求条件の種類により,WAITING状態を以下に示す6種類に細分化し,管理しています。
なお,WAITING状態からの処理再開は,処理の実行が中断した箇所からとなります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキストなど)は,中断直前の値が復元されます。
また,RI78V4では,要求条件の種類により,WAITING状態を以下に示す6種類に細分化し,管理しています。
強制的に処理の実行を中断させられた状態です。
なお,SUSPENDED状態からの処理再開は,処理の実行が中断した箇所からの再開となります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキストなど)は,中断直前の値が復元されます。
なお,SUSPENDED状態からの処理再開は,処理の実行が中断した箇所からの再開となります。したがって,処理を再開するうえで必要となる情報(タスク・コンテキストなど)は,中断直前の値が復元されます。
WAITING状態とSUSPENDED状態が複合した状態です。
なお,WAITING状態が解除された際にはSUSPENDED状態へ,SUSPENDED状態が解除された際にはWAITING状態へと遷移します。
なお,WAITING状態が解除された際にはSUSPENDED状態へ,SUSPENDED状態が解除された際にはWAITING状態へと遷移します。
これにより,RI78V4では,実行可能な状態(RUNNING状態,および,READY状態)へと遷移している全タスクの中から“最も高い優先度(最高優先度)を持つタスク”を選び出し,CPUの利用権を与えます。
- 現在優先度
タスクがDORMANT状態からREADY状態へと遷移したのち,再びDORMANT状態へと遷移するまでの優先度の総称です。
したがって,タスクがDORMANT状態からREADY状態へと遷移した際の現在優先度は“初期優先度と同値”となり,chg_pri,ichg_priの発行により優先度の変更が行われた際の現在優先度は“変更後優先度と同値”となります。
タスクがDORMANT状態からREADY状態へと遷移したのち,再びDORMANT状態へと遷移するまでの優先度の総称です。
したがって,タスクがDORMANT状態からREADY状態へと遷移した際の現在優先度は“初期優先度と同値”となり,chg_pri,ichg_priの発行により優先度の変更が行われた際の現在優先度は“変更後優先度と同値”となります。
- 静的な生成
タスクの静的な生成は,システム・コンフィギュレーション・ファイルにタスク情報を定義することにより実現されます。
RI78V4では,カーネル初期化部において,情報ファイルに格納されているデータをもとにタスクの生成処理を実行し,管理対象とします。
タスクの静的な生成は,システム・コンフィギュレーション・ファイルにタスク情報を定義することにより実現されます。
RI78V4では,カーネル初期化部において,情報ファイルに格納されているデータをもとにタスクの生成処理を実行し,管理対象とします。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ............ /*タスクの本体処理*/ ............ ext_tsk ( ); /*自タスクの終了*/ } |
- スタックの切り替え
RI78V4では,タスクを切り替える際に“切り替え先のタスク用スタック(タスク・スタック)への切り替え処理”を実行しています。
したがって,ユーザは,タスク内でスタックの切り替えに関する処理を記述する必要はありません。
RI78V4では,タスクを切り替える際に“切り替え先のタスク用スタック(タスク・スタック)への切り替え処理”を実行しています。
したがって,ユーザは,タスク内でスタックの切り替えに関する処理を記述する必要はありません。
- 割り込み状態
RI78V4では,タスクをREADY状態からRUNNING状態へと遷移した際,“タスク情報において指定した初期割り込み状態”としています。
したがって,タスク内で割り込み状態を変更(禁止/許可)する場合は,__DI,__EI関数の呼び出しが必要となります。
RI78V4では,タスクをREADY状態からRUNNING状態へと遷移した際,“タスク情報において指定した初期割り込み状態”としています。
したがって,タスク内で割り込み状態を変更(禁止/許可)する場合は,__DI,__EI関数の呼び出しが必要となります。
- act_tsk,iact_tsk
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させます。
これにより,対象タスクは,初期優先度に対応したレディ・キューの最後尾にキューイングされ,RI78V4のスケジューリング対象となります。
ただし,本サービス・コールを発行した際,対象タスクがDORMANT状態以外の状態へと遷移していた場合には,状態操作処理は実行されず,起動要求カウンタの加算処理(起動要求カウンタに0x1を加算)が実行されます。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させます。
これにより,対象タスクは,初期優先度に対応したレディ・キューの最後尾にキューイングされ,RI78V4のスケジューリング対象となります。
ただし,本サービス・コールを発行した際,対象タスクがDORMANT状態以外の状態へと遷移していた場合には,状態操作処理は実行されず,起動要求カウンタの加算処理(起動要求カウンタに0x1を加算)が実行されます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID tskid = ID_tskA; /*変数の宣言,初期化*/ ............ ............ act_tsk ( tskid ); /*タスクの起動(起動要求をキューイングする)*/ ............ ............ } |
備考1 RI78V4が管理する起動要求カウンタは,7ビット幅で構成されています。このため,本サービス・コールの発行により,起動要求数が最大カウント値127を越える場合には,カウンタ操作処理は実行されず,戻り値として“E_QOVR”が返されます。
- sta_tsk,ista_tsk
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させます。
これにより,対象タスクは,初期優先度に対応したレディ・キューの最後尾にキューイングされ,RI78V4のスケジューリング対象となります。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクをDORMANT状態からREADY状態へと遷移させます。
これにより,対象タスクは,初期優先度に対応したレディ・キューの最後尾にキューイングされ,RI78V4のスケジューリング対象となります。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID tskid = ID_tskA; /*変数の宣言,初期化*/ VP_INT stacd = 1048575; /*変数の宣言,初期化*/ ............ ............ sta_tsk ( tskid, stacd ); /*タスクの起動(起動要求をキューイングしない)*/ ............ ............ } |
- can_act
パラメータtskidで指定されたタスクにキューイングされている起動要求をすべて解除(起動要求カウンタに0x0を設定)します。
なお,本サービス・コールが正常終了した際には,戻り値として“解除した起動要求数”が返されます。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクにキューイングされている起動要求をすべて解除(起動要求カウンタに0x0を設定)します。
なお,本サービス・コールが正常終了した際には,戻り値として“解除した起動要求数”が返されます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ER_UINT ercd; /*変数の宣言*/ ID tskid = ID_tskA; /*変数の宣言,初期化*/ ............ ............ ercd = can_act ( tskid ); /*起動要求の解除*/ if ( ercd >= 0x0 ) { ............ /*正常終了処理*/ ............ } ............ ............ } |
- ext_tsk
自タスクをRUNNING状態からDORMANT状態へと遷移させます。
これにより,自タスクは,レディ・キューから外れ,RI78V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,自タスクに起動要求がキューイングされていた(起動要求カウンタが0x0以外であった)場合には,RUNNING状態からDORMANT状態への状態操作処理,および,起床要求カウンタの減算処理(起床要求カウンタから0x1を減算)を行ったのち,DORMANT状態からREADY状態への状態操作処理もあわせて実行されます。
以下に,本サービス・コールの記述例を示します。
自タスクをRUNNING状態からDORMANT状態へと遷移させます。
これにより,自タスクは,レディ・キューから外れ,RI78V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,自タスクに起動要求がキューイングされていた(起動要求カウンタが0x0以外であった)場合には,RUNNING状態からDORMANT状態への状態操作処理,および,起床要求カウンタの減算処理(起床要求カウンタから0x1を減算)を行ったのち,DORMANT状態からREADY状態への状態操作処理もあわせて実行されます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ............ ............ ext_tsk ( ); /*自タスクの終了*/ } |
備考1 本サービス・コールでは,自タスクがsig_sem,get_mpfなどの発行により獲得したOS資源の返却は行いません。したがって,獲得中のOS資源については,本サービス・コールを発行する以前に返却する必要があります。
- ter_tsk
パラメータtskidで指定されたタスクを強制的にDORMANT状態へと遷移させます。
これにより,対象タスクは,RI78V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,対象タスクに起動要求がキューイングされていた(起動要求カウンタが0x0以外であった)場合には,DORMANT状態への状態操作処理,および,起床要求カウンタの減算処理(起床要求カウンタから0x1を減算)を行ったのち,DORMANT状態からREADY状態への状態操作処理もあわせて実行されます。
以下に,本サービス・コールの記述例を示します。
パラメータtskidで指定されたタスクを強制的にDORMANT状態へと遷移させます。
これにより,対象タスクは,RI78V4のスケジューリング対象から除外されます。
ただし,本サービス・コールを発行した際,対象タスクに起動要求がキューイングされていた(起動要求カウンタが0x0以外であった)場合には,DORMANT状態への状態操作処理,および,起床要求カウンタの減算処理(起床要求カウンタから0x1を減算)を行ったのち,DORMANT状態からREADY状態への状態操作処理もあわせて実行されます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID tskid = ID_tskA; /*変数の宣言,初期化*/ ............ ............ ter_tsk ( tskid ); /*他タスクの強制終了*/ ............ ............ } |
備考1 本サービス・コールでは,対象タスクがsig_sem,get_mpfなどの発行により獲得したOS資源の返却は行いません。したがって,獲得中のOS資源については,本サービス・コールを発行する以前に返却する必要があります。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID tskid = ID_tskA; /*変数の宣言,初期化*/ PRI tskpri = 15; /*変数の宣言,初期化*/ ............ ............ chg_pri ( tskid, tskpri ); /*優先度の変更*/ ............ ............ } |
備考 本サービス・コールを発行した際,対象タスクがRUNNING状態,またはREADY状態であった場合には,優先度の変更処理を実行したのち,パラメータtskpriで指定された優先度に対応したレディ・キューの最後尾にキューイングし直す処理もあわせて実行されます。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID tskid = ID_tskA; /*変数の宣言,初期化*/ T_RTSK pk_rtsk; /*データ構造体の宣言*/ STAT tskstat; /*変数の宣言*/ PRI tskpri; /*変数の宣言*/ STAT tskwait; /*変数の宣言*/ ID wobjid; /*変数の宣言*/ UINT actcnt; /*変数の宣言*/ UINT wupcnt; /*変数の宣言*/ UINT suscnt; /*変数の宣言*/ ............ ............ ref_tsk ( tskid, &pk_rtsk ); /*タスクの状態参照*/ tskstat = pk_rtsk.tskstat; /*現在状態の獲得*/ tskpri = pk_rtsk.tskpri; /*現在優先度の獲得*/ tskwait = pk_rtsk.tskwait; /*待ち要因の獲得*/ wobjid = pk_rtsk.wobjid; /*管理オブジェクトのIDの獲得*/ actcnt = pk_rtsk.actcnt; /*起動要求数の獲得*/ wupcnt = pk_rtsk.wupcnt; /*起床要求数の獲得*/ suscnt = pk_rtsk.suscnt; /*サスペンド要求数の獲得*/ ............ ............ } |