第8章  システム状態管理機能


本章では,RI78V4が提供しているシステム状態管理機能について解説しています。

8.1 概  要

RI78V4におけるシステム状態管理機能では,CPUロック状態への移行,ディスパッチ禁止状態への移行などといったシステムの状態を操作する機能のほかに,コンテキスト種別の参照,CPUロック状態の参照などといったシステムの状態を参照する機能も提供しています。

8.2 レディ・キューの回転

レディ・キューの回転は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- rot_rdqirot_rdq
パラメータtskpriで指定された優先度に対応したレディ・キューの先頭タスクを最後尾につなぎかえ,タスクの実行順序を明示的に変更します。
以下に,本サービス・コールを利用した際の状態変化を示します。


図8−1  レディ・キューの回転



以下に,本サービス・コールの記述例を示します。

 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_cychdr ( void )
 {
         PRI     tskpri = 8;             /*変数の宣言,初期化*/
 
         ............
         ............
 
         irot_rdq ( tskpri );            /*レディ・キューの回転*/
 
         ............
         ............
 
         return;                         /*周期ハンドラの終了*/
 }
 

備考1 本サービス・コールでは,回転要求のキューイングが行われません。このため,該当優先度に対応したレディ・キューにタスクが1つもキューイングされていなかった場合には,何も処理は行わず,エラーとしても扱いません。

備考2 本サービス・コールを周期ハンドラなどから一定周期で発行することにより,ラウンドロビン・スケジューリングを実現することができます。

備考3 レディ・キューは,優先度をキーとしたハッシュ・テーブルであり,実行可能な状態(READY状態,またはRUNNING状態)へと遷移したタスクがFIFO順でキューイングされます。
このため,スケジューラは,起動された際にレディ・キューの優先度高位から“タスクの検出処理”を実行し,キューイングされているタスクを検出した際には,該当優先度の先頭タスクにCPUの利用権を与えることにより,RI78V4のスケジューリング方式を実現しています。


8.3 RUNNING状態のタスクの参照

RUNNING状態のタスクの参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- get_tidiget_tid
RUNNING状態のタスクのIDをパラメータp_tskidで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。


 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_cychdr ( void )
 {
         ID      p_tskid;                /*変数の宣言*/
 
         ............
         ............
 
         iget_tid ( &p_tskid );          /*RUNNING状態のタスクの参照*/
 
         ............
         ............
 
         return;                         /*周期ハンドラの終了*/
 }
 

備考 本サービス・コールでは,RUNNING状態へと遷移しているタスクが存在しなかった場合(IDLE状態)には,パラメータp_tskidで指定された領域にTSK_NONEを格納します。

8.4 CPUロック状態への移行

CPUロック状態への移行は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- loc_cpuiloc_cpu
システム状態種別をCPUロック状態へと変更します。
これにより,本サービス・コールの発行からunl_cpu,またはiunl_cpuが発行されるまでの間,“マスカブル割り込みの受け付け処理”が禁止されるとともに,サービス・コールの発行が制限されます。
なお,RI78V4では,本サービス・コールの発行からunl_cpu,またはiunl_cpuが発行されるまでの間にマスカブル割り込みが発生した場合には,該当割り込み処理(割り込みハンドラ)への移行をunl_cpu,またはiunl_cpuが発行されるまで遅延しています。
また,RI78V4では,CPUロック状態で発行可能なサービス・コールを以下に示したものに制限しています。




 
サービス・コール名

機能概要

CPUロック状態への移行

CPUロック状態の解除

コンテキスト種別の参照

CPUロック状態の参照

ディスパッチ禁止状態の参照

ディスパッチ保留状態の参照



以下に,本サービス・コールを利用した際の処理の流れを示します。

図8−2  CPUロック状態への移行



以下に,本サービス・コールの記述例を示します。

 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_task ( VP_INT exinf )
 {
         ............
         ............
 
         loc_cpu ( );                    /*CPUロック状態への移行*/
 
         ............                    /*CPUロック状態*/
         ............
 
         unl_cpu ( );                    /*CPUロック状態の解除*/
 
         ............
         ............
 }
 

備考1 本サービス・コールの発行により変更したCPUロック状態の解除は,本サービス・コールを発行した処理プログラムが終了する以前に行う必要があります。

備考2 本サービス・コールでは,ロック要求のキューイングが行われません。このため,システム状態種別がCPUロック状態であった場合には,何も処理は行わず,エラーとしても扱いません。

備考3 RI78V4では,割り込みマスク・フラグ・レジスタMKxx,および,プログラム・ステータス・ワードPSWのインサービス・プライオリティ・フラグISPxを操作して,“マスカブル割り込みの受け付け禁止”を実現しています。このため,本サービス・コールの発行からunl_cpu,またはiunl_cpuが発行されるまでの間,処理プログラムから該当レジスタを操作することは禁止されています。

8.5 CPUロック状態の解除

CPUロック状態の解除は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- unl_cpuiunl_cpu
システム状態種別を非CPUロック状態へと変更します。
これにより,loc_cpu,またはiloc_cpuの発行により禁止されていた“マスカブル割り込みの受け付け処理”が許可されるとともに,および,サービス・コールの発行制限が解除されます。
なお,RI78V4では,loc_cpu,またはiloc_cpuの発行から本サービス・コールが発行されるまでの間にマスカブル割り込みが発生した場合には,該当割り込み処理(割り込みハンドラ)への移行を本サービス・コールが発行されるまで遅延しています。
以下に,本サービス・コールの記述例を示します。




 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_task ( VP_INT exinf )
 {
         ............
         ............
 
         loc_cpu ( );                    /*CPUロック状態への移行*/
 
         ............                    /*CPUロック状態*/
         ............
 
         unl_cpu ( );                    /*CPUロック状態の解除*/
 
         ............
         ............
 }
 

備考1 本サービス・コールでは,解除要求のキューイングが行われません。このため,システム状態種別が非CPUロック状態であった場合には,何も処理は行わず,エラーとしても扱いません。

備考2 RI78V4では,割り込みマスク・フラグ・レジスタMKxx,および,プログラム・ステータス・ワードPSWのインサービス・プライオリティ・フラグISPxを操作して,“マスカブル割り込みの受け付け許可”を実現しています。このため,loc_cpu,またはiloc_cpuの発行から本サービス・コールが発行されるまでの間,処理プログラムから該当レジスタを操作することは禁止されています。

8.6 ディスパッチ禁止状態への移行

ディスパッチ禁止状態への移行は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- dis_dsp
システム状態種別をディスパッチ禁止状態へと変更します。
これにより,本サービス・コールの発行からena_dspが発行されるまでの間,ディスパッチ処理(タスクのスケジューリング処理)が禁止されます。
なお,RI78V4では,本サービス・コールの発行からena_dspが発行されるまでの間に“ディスパッチ処理を伴うサービス・コール(chg_prisig_semなど)”が発行された場合には,キュー操作,カウンタ操作などといった処理を行うだけであり,実際のディスパッチ処理は,ena_dspが発行されるまで遅延され,一括して行うようにしています。
以下に,本サービス・コールを利用した際の処理の流れを示します。




図8−3  ディスパッチ禁止状態への移行



以下に,本サービス・コールの記述例を示します。

 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_task ( VP_INT exinf )
 {
         ............
         ............
 
         dis_dsp ( );                    /*ディスパッチ禁止状態への移行*/
 
         ............                    /*ディスパッチ禁止状態*/
         ............
 
         ena_dsp ( );                    /*ディスパッチ禁止状態の解除*/
 
         ............
         ............
 }
 

備考1 本サービス・コールでは,禁止要求のキューイングが行われません。このため,システム状態種別がディスパッチ禁止状態であった場合には,何も処理は行わず,エラーとしても扱いません。

備考2 本サービス・コールの発行により変更したディスパッチ禁止状態の解除は,本サービス・コールを発行したタスクがDORMANT状態へと遷移する以前に行う必要があります。

8.7 ディスパッチ禁止状態の解除

ディスパッチ禁止状態の解除は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- ena_dsp
システム状態種別をディスパッチ許可状態へと変更します。
これにより,dis_dspの発行により禁止されていたディスパッチ処理(タスクのスケジューリング処理)が許可されます。
なお,RI78V4では,dis_dspの発行から本サービス・コールが発行されるまでの間に“ディスパッチ処理を伴うサービス・コール(chg_prisig_semなど)”が発行された場合には,キュー操作,カウンタ操作などといった処理を行うだけであり,実際のディスパッチ処理は,本サービス・コールが発行されるまで遅延され,一括して行うようにしています。
以下に,本サービス・コールの記述例を示します。




 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_task ( VP_INT exinf )
 {
         ............
         ............
 
         dis_dsp ( );                    /*ディスパッチ禁止状態への移行*/
 
         ............                    /*ディスパッチ禁止状態*/
         ............
 
         ena_dsp ( );                    /*ディスパッチ禁止状態の解除*/
 
         ............
         ............
 }
 

備考 本サービス・コールでは,許可要求のキューイングが行われません。このため,システム状態種別がディスパッチ許可状態であった場合には,何も処理は行わず,エラーとしても扱いません。

8.8 コンテキスト種別の参照

コンテキスト種別の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- sns_ctx
本サービス・コールを発行した処理プログラムのコンテキスト種別(非タスク・コンテキスト,タスク・コンテキスト)を獲得します。
なお,本サービス・コールが正常終了した際には,戻り値として“獲得したコンテキスト種別(TRUE:非タスク・コンテキスト,FALSE:タスク・コンテキスト)”が返されます。


非タスク・コンテキスト: 周期ハンドラ,割り込みハンドラ

タスク・コンテキスト: タスク

以下に,本サービス・コールの記述例を示します。

 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_sub ( void )
 {
         BOOL    ercd;                   /*変数の宣言*/
 
         ............
         ............
 
         ercd = sns_ctx ( );             /*コンテキスト種別の参照*/
 
         if ( ercd == TRUE ) {
                 ............            /*非タスク・コンテキスト*/
                 ............
         } else if ( ercd == FALSE ) {
                 ............            /*タスク・コンテキスト*/
                 ............
         }
 
         ............
         ............
 }
 

8.9 CPUロック状態の参照

CPUロック状態の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- sns_loc
本サービス・コールを発行した際のシステム状態種別(CPUロック状態,非CPUロック状態)を獲得します。
なお,本サービス・コールが正常終了した際には,戻り値として“獲得したシステム状態種別(TRUE:CPUロック状態,FALSE:非CPUロック状態)”が返されます。
以下に,本サービス・コールの記述例を示します。



 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_sub ( void )
 {
         BOOL    ercd;                   /*変数の宣言*/
 
         ............
         ............
 
         ercd = sns_loc ( );             /*CPUロック状態の参照*/
 
         if ( ercd == TRUE ) {
                 ............            /*CPUロック状態*/
                 ............
         } else if ( ercd == FALSE ) {
                 ............            /*非CPUロック状態*/
                 ............
         }
 
         ............
         ............
 }
 

備考 CPUロック状態へはloc_cpu,またはiloc_cpuを発行することにより,非CPUロック状態へはunl_cpu,またはiunl_cpuを発行することにより遷移します。

8.10 ディスパッチ禁止状態の参照

ディスパッチ禁止状態の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- sns_dsp
本サービス・コールを発行した際のシステム状態種別(ディスパッチ禁止状態,ディスパッチ許可状態)を獲得します。
なお,本サービス・コールが正常終了した際には,戻り値として“獲得したシステム状態種別(TRUE:ディスパッチ禁止状態,FALSE:ディスパッチ許可状態)”が返されます。
以下に,本サービス・コールの記述例を示します。



 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_sub ( void )
 {
         BOOL    ercd;                   /*変数の宣言*/
 
         ............
         ............
 
         ercd = sns_dsp ( );             /*ディスパッチ禁止状態の参照*/
 
         if ( ercd == TRUE ) {
                 ............            /*ディスパッチ禁止状態*/
                 ............
         } else if ( ercd == FALSE ) {
                 ............            /*ディスパッチ許可状態*/
                 ............
         }
 
         ............
         ............
 }
 

備考 ディスパッチ禁止状態へはdis_dspを発行することにより,ディスパッチ許可状態へはena_dspを発行することにより遷移します。

8.11 ディスパッチ保留状態の参照

ディスパッチ保留状態の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- sns_dpn
本サービス・コールを発行した際のシステム状態種別(ディスパッチ保留状態であるか否か)を獲得します。
なお,本サービス・コールが正常終了した際には,戻り値として“獲得したシステム状態種別(TRUE:ディスパッチ保留状態,FALSE:非ディスパッチ保留状態)”が返されます。
以下に,本サービス・コールの記述例を示します。



 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_sub ( void )
 {
         BOOL    ercd;                   /*変数の宣言*/
 
         ............
         ............
 
         ercd = sns_dpn ( );             /*ディスパッチ保留状態の参照*/
 
         if ( ercd == TRUE ) {
                 ............            /*ディスパッチ保留状態*/
                 ............
         } else if ( ercd == FALSE ) {
                 ............            /*非ディスパッチ保留状態*/
                 ............
         }
 
         ............
         ............
 }
 

備考 ディスパッチ保留状態とは,dis_dsploc_cpuiloc_cpuといったサービス・コールを発行して明示的にディスパッチ処理(タスクのスケジューリング処理)の実行が禁止された状態,および,非タスクが処理を実行中の状態を指します。