第7章 時間管理機能
備考 RI78V4では,タイマ割り込みを発生させるハードウエア(クロック・コントローラなど)の初期化処理を行いません。したがって,該当初期化処理については,ブート処理,または初期化ルーチンにおいて,ユーザが記述する必要があります。
タイマ・ハンドラは,タスクの遅延起床,WAITING状態のタイムアウト,周期ハンドラの起動を実現するうえで必要となる処理を切り出した時間管理処理専用ルーチンであり,タイマ割り込みが発生した際に起動する割り込みハンドラから呼び出されます。
タイマ・ハンドラの登録は,CF78V4がシステム・コンフィギュレーション・ファイルに定義された基本クロック用タイマ割り込み要因を元に割り込み情報定義ファイルに出力するため,ユーザは,タイマ・ハンドラの登録処理を記述する必要はありません。
遅延起床とは,一定の時間が経過するまでの間,自タスクをRUNNING状態からWAITING状態へと遷移させ,一定の時間が経過した際には,該当タスクをWAITING状態からREADY状態へと遷移させるものです。
タイムアウトとは,タスクから発行された要求条件が即時成立しなかった場合,一定の時間が経過するまでの間,該当タスクをRUNNING状態からWAITING状態へと遷移させ,一定の時間が経過した際には,要求条件の成立/不成立を問わず,該当タスクをWAITING状態からREADY状態へと遷移させるものです。
なお,RI78V4では,周期ハンドラを“非タスク(タスクとは独立したもの)”として位置づけています。このため,起動周期に達した際には,システム内で最高優先度を持つタスクが処理を実行中であっても,その処理は中断され,周期ハンドラに制御が移ります。
- 静的な生成
周期ハンドラの静的な生成は,システム・コンフィギュレーション・ファイルに周期ハンドラ情報を定義することにより実現されます。
RI78V4では,カーネル初期化部において,情報ファイルに格納されているデータをもとに周期ハンドラの生成処理を実行し,管理対象とします。
周期ハンドラの静的な生成は,システム・コンフィギュレーション・ファイルに周期ハンドラ情報を定義することにより実現されます。
RI78V4では,カーネル初期化部において,情報ファイルに格納されているデータをもとに周期ハンドラの生成処理を実行し,管理対象とします。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_cychdr ( void ) { ............ /*周期ハンドラの本体処理*/ ............ return; /*周期ハンドラの終了*/ } |
$INCLUDE (kernel.inc) ;標準ヘッダ・ファイルの定義 $INCLUDE (kernel_id.inc) ;システム情報ヘッダ・ファイルの定義 .PUBLIC _func_cychdr .SECTION .text, TEXT _func_cychdr: ............ ;周期ハンドラの本体処理 ............ RET ;周期ハンドラの終了 |
- スタックの切り替え
RI78V4では,周期ハンドラに制御を移す際に“システム・スタックへの切り替え処理”を,周期ハンドラから制御を戻す際に“切り替え先の処理プログラム用スタック(システム・スタック,またはタスク・スタック)への切り替え処理”を実行しています。
したがって,ユーザは,周期ハンドラ内でスタックの切り替えに関する処理を記述する必要はありません。
RI78V4では,周期ハンドラに制御を移す際に“システム・スタックへの切り替え処理”を,周期ハンドラから制御を戻す際に“切り替え先の処理プログラム用スタック(システム・スタック,またはタスク・スタック)への切り替え処理”を実行しています。
したがって,ユーザは,周期ハンドラ内でスタックの切り替えに関する処理を記述する必要はありません。
- 割り込み状態
RI78V4では,周期ハンドラに制御を移す際に“マスカブル割り込みの受け付けが禁止された状態”としています。
したがって,周期ハンドラ内で割り込み状態を変更(許可)する場合は,__EI関数の呼び出しが必要となります。
RI78V4では,周期ハンドラに制御を移す際に“マスカブル割り込みの受け付けが禁止された状態”としています。
したがって,周期ハンドラ内で割り込み状態を変更(許可)する場合は,__EI関数の呼び出しが必要となります。
- サービス・コールの発行
RI78V4では,周期ハンドラを“非タスク”として位置づけています。
このため,周期ハンドラ内で発行可能なサービス・コールは,“非タスクから発行可能なサービス・コール”に限られます。
RI78V4では,周期ハンドラを“非タスク”として位置づけています。
このため,周期ハンドラ内で発行可能なサービス・コールは,“非タスクから発行可能なサービス・コール”に限られます。
備考2 RI78V4では,周期ハンドラ内の処理を高速に終了させる目的から,周期ハンドラ内の処理が完了するまでの間に“ディスパッチ処理(タスクのスケジューリング処理)を伴うサービス・コール(ichg_pri,isig_semなど)”が発行された場合には,キュー操作,カウンタ操作などといった処理を行うだけであり,実際のディスパッチ処理は,周期ハンドラからの復帰命令(return命令の発行など)が発行されるまで遅延され,一括して行うようにしています。
- sta_cyc
パラメータcycidで指定された周期ハンドラを動作停止状態(STP状態)から動作開始状態(STA状態)へと遷移させます。
これにより,対象周期ハンドラは,RI78V4の起動対象となります。
以下に,本サービス・コールの記述例を示します。
パラメータcycidで指定された周期ハンドラを動作停止状態(STP状態)から動作開始状態(STA状態)へと遷移させます。
これにより,対象周期ハンドラは,RI78V4の起動対象となります。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID cycid = ID_cycA; /*変数の宣言,初期化*/ ............ ............ sta_cyc ( cycid ); /*動作開始状態(STA状態)への移行*/ ............ ............ } |
コンフィギュレーション時に定義した起動位相(初期起動位相cycphs,起動周期cyctim)で対象周期ハンドラに対する起動タイミング設定処理が行われます。
ただし,対象周期ハンドラの動作状態が開始状態の場合には,本サービス・コールを発行しても何も処理は行わず,エラーとしても扱いません。
ただし,対象周期ハンドラの動作状態が開始状態の場合には,本サービス・コールを発行しても何も処理は行わず,エラーとしても扱いません。
本サービス・コールの発行を基準点とした起動位相(起動周期cyctim)で対象周期ハンドラに対する起動タイミング設定処理が行われます。
なお,起動タイミング設定処理については,対象周期ハンドラの動作状態に関係なく実行されます。
なお,起動タイミング設定処理については,対象周期ハンドラの動作状態に関係なく実行されます。
- stp_cyc
パラメータcycidで指定された周期ハンドラを動作開始状態(STA状態)から動作停止状態(STP状態)へと遷移させます。
これにより,対象周期ハンドラは,本サービス・コールの発行からsta_cycが発行されるまでの間,RI78V4の起動対象から除外されます。
以下に,本サービス・コールの記述例を示します。
パラメータcycidで指定された周期ハンドラを動作開始状態(STA状態)から動作停止状態(STP状態)へと遷移させます。
これにより,対象周期ハンドラは,本サービス・コールの発行からsta_cycが発行されるまでの間,RI78V4の起動対象から除外されます。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID cycid = ID_cycA; /*変数の宣言,初期化*/ ............ ............ stp_cyc ( cycid ); /*動作停止状態(STP状態)への移行*/ ............ ............ } |
- ref_cyc
パラメータcycidで指定された周期ハンドラの周期ハンドラ状態情報(現在状態など)をパラメータpk_rcycで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
パラメータcycidで指定された周期ハンドラの周期ハンドラ状態情報(現在状態など)をパラメータpk_rcycで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/ #include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/ void func_task ( VP_INT exinf ) { ID cycid = ID_cycA; /*変数の宣言,初期化*/ T_RCYC pk_rcyc; /*データ構造体の宣言*/ STAT cycstat; /*変数の宣言*/ RELTIM lefttim; /*変数の宣言*/ ............ ............ ref_cyc ( cycid, &pk_rcyc ); /*周期ハンドラの状態参照*/ cycstat = pk_rcyc.cycstat; /*現在状態の獲得*/ lefttim = pk_rcyc.lefttim; /*残り時間の獲得*/ ............ ............ } |