第5章 同期通信機能
本章では,RI850V4が提供している同期通信機能について解説しています。
マルチタスク処理では,並行に動作するタスクが限られた数の資源(A/Dコンバータ,ファイルなど)を同時に使用するといった資源使用の競合を防ぐ機能(排他制御機能)が必要となります。そこで,RI850V4では,このような資源使用の競合を防ぐ機能として“非負数の計数型セマフォ”を提供しています。
RI850V4では,セマフォの静的な生成のみサポートしています。処理プログラムからサービス・コールを発行して動的に生成することはできません。
セマフォの静的生成とは,システム・コンフィギュレーション・ファイルで静的API“CRE_SEM”を使用してセマフォを定義することをいいます。
資源の獲得は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
wai_sem
パラメータ
semidで指定されたセマフォから資源を獲得(セマフォ・カウンタから0x1を減算)します。
ただし,本サービス・コールを発行した際,対象セマフォから資源を獲得することができなかった(空き資源が存在しなかった)場合には,資源の獲得は行わず,自タスクを対象セマフォの待ちキューにキューイングしたのち,RUNNING状態からWAITING状態(資源獲得待ち状態)へと遷移させます。
なお,資源獲得待ち状態の解除は,以下の場合に行われ,資源獲得待ち状態からREADY状態へと遷移します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
ER ercd; /*変数の宣言*/
ID semid = ID_SEM1; /*変数の宣言,初期化*/
............
............
ercd = wai_sem ( semid ); /*資源の獲得*/
if ( ercd == E_OK ) {
............ /*正常終了処理*/
............
} else if ( ercd == E_RLWAI ) {
............ /*強制終了処理*/
............
}
............
............
}
|
備考 自タスクを対象セマフォの待ちキューにキューイングする際のキューイング方式は,コンフィギュレーション時に定義された順(FIFO順,優先度順)に行われます。
-
pol_sem,
ipol_sem
パラメータ
semidで指定されたセマフォから資源を獲得(セマフォ・カウンタから0x1を減算)します。
ただし,本サービス・コールを発行した際,対象セマフォから資源を獲得することができなかった(空き資源が存在しなかった)場合には,資源の獲得は行わず,戻り値としてE_TMOUTを返します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
ER ercd; /*変数の宣言*/
ID semid = ID_SEM1; /*変数の宣言,初期化*/
............
............
ercd = pol_sem ( semid ); /*資源の獲得(ポーリング)*/
if ( ercd == E_OK ) {
............ /*ポーリング成功処理*/
............
} else if ( ercd == E_TMOUT ) {
............ /*ポーリング失敗処理*/
............
}
............
............
}
|
-
twai_sem
パラメータ
semidで指定されたセマフォから資源を獲得(セマフォ・カウンタから0x1を減算)します。
ただし,本サービス・コールを発行した際,対象セマフォから資源を獲得することができなかった(空き資源が存在しなかった)場合には,資源の獲得は行わず,自タスクを対象セマフォの待ちキューにキューイングしたのち,RUNNING状態からタイムアウト付きのWAITING状態(資源獲得待ち状態)へと遷移させます。
なお,資源獲得待ち状態の解除は,以下の場合に行われ,資源獲得待ち状態からREADY状態へと遷移します。
|
|
|
|
|
|
|
|
|
|
パラメータ tmoutで指定された待ち時間が経過した
|
|
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
ER ercd; /*変数の宣言*/
ID semid = ID_SEM1; /*変数の宣言,初期化*/
TMO tmout = 3600; /*変数の宣言,初期化*/
............
............
/*資源の獲得(タイムアウト付き)*/
ercd = twai_sem ( semid, tmout );
if ( ercd == E_OK ) {
............ /*正常終了処理*/
............
} else if ( ercd == E_RLWAI ) {
............ /*強制終了処理*/
............
} else if ( ercd == E_TMOUT ) {
............ /*タイムアウト処理*/
............
}
............
............
}
|
備考1 自タスクを対象セマフォの待ちキューにキューイングする際のキューイング方式は,コンフィギュレーション時に定義された順(FIFO順,優先度順)に行われます。
資源の返却は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
sig_sem,
isig_sem
パラメータ
semidで指定されたセマフォに資源を返却(セマフォ・カウンタに0x1を加算)します。
ただし,本サービス・コールを発行した際,対象セマフォの待ちキューにタスクがキューイングされていた場合には,資源の返却(セマフォ・カウンタの加算処理)は行わず,該当タスク(待ちキューの先頭タスク)に資源を渡します。これにより,該当タスクは,待ちキューから外れ,WAITING状態(資源獲得待ち状態)からREADY状態へ,またはWAITING-SUSPENDED状態からSUSPENDED状態へと遷移します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
ID semid = ID_SEM1; /*変数の宣言,初期化*/
............
............
sig_sem ( semid ); /*資源の返却*/
............
............
}
|
備考 RI850V4では,セマフォの資源数として取り得る最大値(
最大資源数maxsem)をコンフィギュレーション時に定義させています。このため,本サービス・コールでは,資源数が
最大資源数maxsemを越えるような場合には,資源の返却(セマフォ・カウンタの加算処理)は行わず,戻り値としてE_QOVRを返します。
セマフォ詳細情報の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
ref_sem,
iref_sem
パラメータ
semidで指定されたセマフォのセマフォ詳細情報(待ちタスクの有無,現在資源数など)をパラメータ
pk_rsemで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。
#include <kernel.h> /*標準ヘッダ・ファイルの定義*/
#include <kernel_id.h> /*システム情報ヘッダ・ファイルの定義*/
void
task ( VP_INT exinf )
{
ID semid = ID_SEM1; /*変数の宣言,初期化*/
T_RSEM pk_rsem; /*データ構造体の宣言*/
ID wtskid; /*変数の宣言*/
UINT semcnt; /*変数の宣言*/
ATR sematr; /*変数の宣言*/
UINT maxsem; /*変数の宣言*/
............
............
ref_sem ( semid, &pk_rsem ); /*セマフォ詳細情報の参照*/
wtskid = pk_rsem.wtskid; /*待ちタスクの有無の獲得*/
semcnt = pk_rsem.semcnt; /*現在資源数の獲得*/
sematr = pk_rsem.sematr; /*属性の獲得*/
maxsem = pk_rsem.maxsem; /*最大資源数の獲得*/
............
............
}
|