第8章 システム状態管理機能
本章では,RI850V4が提供しているシステム状態管理機能について解説しています。
RI850V4におけるシステム状態管理機能では,レディ・キューの回転,スケジューラの起動などといったシステムの状態を操作する機能のほかに,コンテキスト種別の参照,CPUロック状態の参照などといったシステムの状態を参照する機能も提供しています。
レディ・キューの回転は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
rot_rdq,
irot_rdq
パラメータ
tskpriで指定された優先度に対応したレディ・キューの先頭タスクを最後尾につなぎかえ,タスクの実行順序を明示的に変更します。
以下に,“レディ・キューの回転”を利用した際の状態変化を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
cychdr ( VP_INT exinf )
{
PRI tskpri = 8; /*変数の宣言,初期化*/
............
............
irot_rdq ( tskpri ); /*レディ・キューの回転*/
............
............
return; /*周期ハンドラの終了*/
}
|
備考1 本サービス・コールでは,レディ・キューの対象優先度にタスクが1つもキューイングされていなかった場合には,何も処理は行わず,エラーとしても扱いません。
備考2 本サービス・コールを周期ハンドラなどから一定周期で発行することにより,ラウンドロビン・スケジューリングを実現することができます。
備考3 RI850V4におけるレディ・キューは,優先度をキーとしたハッシュ・テーブルであり,実行可能な状態(RUNNING状態,またはREADY状態)へと遷移したタスクの管理ブロック(タスク管理ブロック)がFIFO順でキューイングされます。このため,スケジューラは,起動された際にレディ・キューの優先度高位から検出処理を実行し,キューイングされているタスクを検出した場合には,該当優先度の先頭タスクにCPUの利用権を与えることにより,RI850V4のスケジューリング方式(優先度方式,FCFS方式)を実現しています。
スケジューラの強制起動は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
vsta_sch
RI850V4のスケジューラを明示的に強制起動します。このため,スケジューリング要求が保留されていた際には,“タスクの切り替え”が発生する場合があります。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
............
............
vsta_sch ( ); /*スケジューラの強制起動*/
............
............
}
|
備考 RI850V4では,本サービス・コールを“コンフィギュレーション時にプリエンプトの受け付け状態を禁止状態(TA_DISPREEMPT)と定義したタスクからRI850V4のスケジューラを起動するための機能”として提供しています。
RUNNING状態のタスクの参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
get_tid,
iget_tid
RUNNING状態のタスクのIDをパラメータ
p_tskidで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
inthdr ( void )
{
ID p_tskid; /*変数の宣言*/
............
............
iget_tid ( &p_tskid ); /*RUNNING状態のタスクIDの参照*/
............
............
return; /*割り込みハンドラの終了*/
}
|
備考 本サービス・コールでは,RUNNING状態へと遷移しているタスクが存在しなかった場合(IDLE状態)には,パラメータ
p_tskidで指定された領域にTSK_NONEを格納しています。
CPUロック状態への移行は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
loc_cpu,
iloc_cpu
システム状態種別をCPUロック解除状態からCPUロック状態へと変更します。これにより,本サービス・コールの発行から
unl_cpu,または
iunl_cpuが発行されるまでの間,“EIレベル・マスカブル割り込みの受け付け”,および“サービス・コール(一部のサービス・コールを除く)の発行”が禁止されます。
なお,RI850V4では,本サービス・コールの発行から
unl_cpu,または
iunl_cpuが発行されるまでの間にEIレベル・マスカブル割り込みが発生した場合には,該当割り込み処理(割り込みハンドラ)への移行を
unl_cpu,または
iunl_cpuが発行されるまで遅延しています。
以下に,“CPUロック状態への移行”を利用した際の処理の流れを示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
............
............
loc_cpu ( ); /*CPUロック状態への移行*/
............ /*CPUロック状態*/
............
unl_cpu ( ); /*CPUロック状態の解除*/
............
............
}
|
備考1 本サービス・コールの発行により変更したCPUロック状態の解除は,本サービス・コールを発行した処理プログラムが終了する以前に行う必要があります。
備考2 本サービス・コールでは,ロック要求のキューイングが行われません。このため,すでに本サービス・コールが発行され,システム状態種別がCPUロック状態へと変更されていた場合には,何も処理は行わず,エラーとしても扱いません。
備考3 本サービス・コールでは,EIレベル・マスカブル割り込みの受け付け禁止処理として,プライオリティ・マスク・レジスタPMRのPM
nビットに対する操作を行います。
なお,操作対象となるPM
nビットは,コンフィギュレーション時に
最大割り込み優先度maxintpriで定義した割り込み優先度範囲となります。
本サービス・コールでは,プログラム・ステータス・ワードPSWのIDビットに対する操作は行われません。
備考4 RI850V4では,一定周期で発生する基本クロック用タイマ割り込みを利用して
時間管理機能を実現しています。このため,本サービス・コールの発行により,該当基本クロック用タイマ割り込みの受け付けを禁止状態へと変更した際には,
時間管理機能が正常に動作しなくなる場合があります。
備考5 RI850V4では,本サービス・コールの発行から
unl_cpu,または
iunl_cpuが発行されるまでの間に“本サービス・コール,またはsns_
xxx以外のサービス・コール”を発行した場合には,戻り値としてE_CTXを返します。
CPUロック状態の解除は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
unl_cpu,
iunl_cpu
システム状態種別をCPUロック状態からCPUロック解除状態へと変更します。これにより,
loc_cpu,または
iloc_cpuの発行により抑制(禁止)されていた“EIレベル・マスカブル割り込みの受け付け”,および“サービス・コールの発行”が許可されます。
なお,RI850V4では,
loc_cpu,または
iloc_cpuの発行から本サービス・コールが発行されるまでの間にEIレベル・マスカブル割り込みが発生した場合には,該当割り込み処理(割り込みハンドラ)への移行を本サービス・コールが発行されるまで遅延しています。
以下に,“CPUロック状態の解除”を利用した際の処理の流れを示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
............
............
loc_cpu ( ); /*CPUロック状態への移行*/
............ /*CPUロック状態*/
............
unl_cpu ( ); /*CPUロック状態の解除*/
............
|
............
}
|
備考1 本サービス・コールでは,解除要求のキューイングが行われません。このため,すでに本サービス・コールが発行され,システム状態種別がCPUロック解除状態へと変更されていた場合には,何も処理は行わず,エラーとしても扱いません。
備考2 本サービス・コールでは,EIレベル・マスカブル割り込みの受け付け許可処理として,プライオリティ・マスク・レジスタPMRのPM
nビットに対する操作を行います。
なお,操作対象となるPM
nビットは,コンフィギュレーション時に
最大割り込み優先度maxintpriで定義した割り込み優先度範囲となります。
本サービス・コールでは,プログラム・ステータス・ワードPSWのIDビットに対する操作は行われません。
備考3 本サービス・コールでは,
dis_dspの発行により変更されたディスパッチ禁止状態の解除処理は行われません。したがって,CPUロック状態以前のシステム状態種別がディスパッチ禁止状態であった場合には,本サービス・コール発行後のシステム状態種別は,ディスパッチ禁止状態となります。
CPUロック状態の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
sns_loc
本サービス・コールを発行した際のシステム状態種別(CPUロック状態,CPUロック解除状態)を獲得します。
なお,本サービス・コールの発行により獲得したシステム状態種別については,戻り値として返します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
BOOL ercd; /*変数の宣言*/
............
............
ercd = sns_loc ( ); /*CPUロック状態の参照*/
if ( ercd == TRUE ) {
............ /*CPUロック状態*/
............
} else if ( ercd == FALSE ) {
............ /*CPUロック解除状態*/
............
}
............
............
}
|
ディスパッチ禁止状態への移行は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
dis_dsp
システム状態種別をディスパッチ許可状態からディスパッチ禁止状態へと変更します。これにより,本サービス・コールの発行から
ena_dspが発行されるまでの間,“タスクのディスパッチ処理”が抑制(禁止)されます。
なお,RI850V4では,本サービス・コールの発行から
ena_dspが発行されるまでの間に“タスクのディスパッチ処理”を伴うサービス・コール(
chg_pri,
sig_semなど)が発行された場合には,キュー操作,カウンタ操作などといった処理を行うだけであり,実際の“タスクのディスパッチ処理”は,
ena_dspが発行されるまで遅延され,一括して行うようにしています。
以下に,“ディスパッチ禁止状態への移行”を利用した際の処理の流れを示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
............
............
dis_dsp ( ); /*ディスパッチ禁止状態への移行*/
............ /*ディスパッチ禁止状態*/
............
ena_dsp ( ); /*ディスパッチ禁止状態の解除*/
............
............
}
|
備考1 本サービス・コールの発行により変更したディスパッチ禁止状態の解除は,本サービス・コールを発行したタスクがDORMANT状態へと遷移する以前に行う必要があります。
備考2 本サービス・コールでは,禁止要求のキューイングが行われません。このため,すでに本サービス・コールが発行され,システム状態種別がディスパッチ禁止状態へと変更されていた場合には,何も処理は行わず,エラーとしても扱いません。
備考3 RI850V4では,本サービス・コールの発行から
ena_dspが発行されるまでの間に“自タスクを状態遷移させる可能性のあるサービス・コール(
wai_sem,
wai_flgなど)”を発行した場合には,要求条件の即時成立/不成立を問わず,戻り値としてE_CTXを返します。
ディスパッチ禁止状態の解除は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
ena_dsp
システム状態種別をディスパッチ禁止状態からディスパッチ許可状態へと変更します。これにより,
dis_dspの発行により抑制(禁止)されていた“タスクのディスパッチ処理”が許可されます。
なお,RI850V4では,
dis_dspの発行から本サービス・コールが発行されるまでの間に“タスクのディスパッチ処理”を伴うサービス・コール(
chg_pri,
sig_semなど)が発行された場合には,キュー操作,カウンタ操作などといった処理を行うだけであり,実際の“タスクのディスパッチ処理”は,本サービス・コールが発行されるまで遅延され,一括して行うようにしています。
以下に,“ディスパッチ禁止状態の解除”を利用した際の処理の流れを示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
............
............
dis_dsp ( ); /*ディスパッチ禁止状態への移行*/
............ /*ディスパッチ禁止状態*/
............
ena_dsp ( ); /*ディスパッチ禁止状態の解除*/
............
............
}
|
備考1 本サービス・コールでは,許可要求のキューイングが行われません。このため,すでに本サービス・コールが発行され,システム状態種別がディスパッチ許可状態へと変更されていた場合には,何も処理は行わず,エラーとしても扱いません。
備考2 RI850V4では,
dis_dspの発行から本サービス・コールが発行されるまでの間に“自タスクを状態遷移させる可能性のあるサービス・コール(
wai_sem,
wai_flgなど)”を発行した場合には,要求条件の即時成立/不成立を問わず,戻り値としてE_CTXを返します。
ディスパッチ禁止状態の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
sns_dsp
本サービス・コールを発行した際のシステム状態種別(ディスパッチ禁止状態,ディスパッチ許可状態)を獲得します。
なお,本サービス・コールの発行により獲得したシステム状態種別については,戻り値として返します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
BOOL ercd; /*変数の宣言*/
............
............
ercd = sns_dsp ( ); /*ディスパッチ禁止状態の参照*/
if ( ercd == TRUE ) {
............ /*ディスパッチ禁止状態*/
............
} else if ( ercd == FALSE ) {
............ /*ディスパッチ許可状態*/
............
}
............
............
}
|
コンテキスト種別の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
sns_ctx
本サービス・コールを発行した処理プログラムのコンテキスト種別(非タスク・コンテキスト,タスク・コンテキスト)を獲得します。
なお,本サービス・コールの発行により獲得したコンテキスト種別については,戻り値として返します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
BOOL ercd; /*変数の宣言*/
............
............
ercd = sns_ctx ( ); /*コンテキスト種別の参照*/
if ( ercd == TRUE ) {
............ /*非タスク・コンテキスト処理*/
............
} else if ( ercd == FALSE ) {
............ /*タスク・コンテキスト処理*/
............
}
............
............
}
|
ディスパッチ保留状態の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
sns_dpn
本サービス・コールを発行した際のシステム状態種別(ディスパッチ保留状態であるか否か)を獲得します。
なお,本サービス・コールの発行により獲得したシステム状態種別については,戻り値として返します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
BOOL ercd; /*変数の宣言*/
............
............
ercd = sns_dpn ( ); /*ディスパッチ保留状態の参照*/
if ( ercd == TRUE ) {
............ /*ディスパッチ保留状態*/
............
} else if ( ercd == FALSE ) {
............ /*非ディスパッチ保留状態*/
............
}
............
............
}
|