第 4 章 µITRON4.0 仕様の機能 79
4.4 同期・通信機能
4.4.3 データキュー
データキューは,1ワードのメッセージ(これをデータと呼ぶ)を受渡しする ことにより,同期と通信を行うためのオブジェクトである.データキュー機能 には,データキューを生成/削除する機能,データキューに対してデータを送 信/強制送信/受信する機能,データキューの状態を参照する機能が含まれ る.データキューはID番号で識別されるオブジェクトである.データキュー のID番号をデータキューIDと呼ぶ.
データキューは,データの送信を待つタスクの待ち行列(送信待ち行列)と データの受信を待つタスクの待ち行列(受信待ち行列)を持つ.また,送信さ れたデータを格納するためのデータキュー領域を持つ.データを送信する側
(イベントを知らせる側)では,送信したいデータをデータキューに入れる.
データキュー領域に空きがない場合は,データキュー領域に空きができるまで データキューへの送信待ち状態になる.データキューへの送信待ち状態になっ たタスクは,そのデータキューの送信待ち行列につながれる.一方,データを 受信する側(イベントを待つ側)では,データキューに入っているデータを一 つ取り出す.データキューにデータが入っていない場合は,次にデータが送ら れてくるまでデータキューからの受信待ち状態になる.データキューからの受 信待ち状態になったタスクは,そのデータキューの受信待ち行列につながれ る.
データキュー領域に格納できるデータの数を0にすることで,同期メッセージ 機能を実現することができる.すなわち,送信側のタスクと受信側のタスク が,それぞれ相手のタスクがサービスコールを呼び出すのを待ち合わせ,両者 がサービスコールを呼び出した時点で,データの受渡しが行われる.
データキューで送受信されるデータ(1ワードのメッセージ)は,整数値であっ ても,送信側と受信側で共有しているメモリ上に置かれたメッセージの先頭番 地であってもよい.送受信されるデータは,送信側から受信側にコピーされる.
データキュー機能に関連して,次のカーネル構成マクロを定義する.
SIZE dtqsz = TSZ_DTQ ( UINT dtqcnt )
dtqcnt 個のデータを格納するのに必要なデータキュー領域のサイズ(バ
イト数)
データキュー生成情報およびデータキュー状態のパケット形式として,次の データ型を定義する.
typedef struct t_cdtq {
ATR dtqatr ; /*データキュー属性*/
UINT dtqcnt ; /*データキュー領域の容量(データの
個数)*/
VP dtq ; /*データキュー領域の先頭番地*/
/*実装独自に他のフィールドを追加してもよい*/
} T_CDTQ ;
typedef struct t_rdtq {
ID stskid ; /*データキューの送信待ち行列の先頭 のタスクのID番号*/
ID rtskid ; /*データキューの受信待ち行列の先頭
のタスクのID番号*/
UINT sdtqcnt ; /*データキューに入っているデータの
数*/
/*実装独自に他のフィールドを追加してもよい*/
} T_RDTQ ;
データキュー機能の各サービスコールの機能コードは次の通りである.
TFN_CRE_DTQ –0x31 cre_dtqの機能コード
TFN_ACRE_DTQ –0xc4 acre_dtqの機能コード
TFN_DEL_DTQ –0x32 del_dtqの機能コード
TFN_SND_DTQ –0x35 snd_dtqの機能コード
TFN_PSND_DTQ –0x36 psnd_dtqの機能コード
TFN_IPSND_DTQ –0x77 ipsnd_dtqの機能コード
TFN_TSND_DTQ –0x37 tsnd_dtqの機能コード
TFN_FSND_DTQ –0x38 fsnd_dtqの機能コード
TFN_IFSND_DTQ –0x78 ifsnd_dtqの機能コード
TFN_RCV_DTQ –0x39 rcv_dtqの機能コード
TFN_PRCV_DTQ –0x3a prcv_dtqの機能コード
TFN_TRCV_DTQ –0x3b trcv_dtqの機能コード
TFN_REF_DTQ –0x3c ref_dtqの機能コード
【スタンダードプロファイル】
スタンダードプロファイルでは,データキューを動的に生成/削除する機能
(cre_dtq,acre_dtq,del_dtq),データキューの状態を参照する機能(ref_dtq)を 除いて,データキュー機能をサポートしなければならない.
スタンダードプロファイルでは,データキュー領域の容量(格納できるデータ の個数)として,少なくとも255以上の値が指定できなければならない.
スタンダードプロファイルでは,TSZ_DTQを定義する必要はない.
【補足説明】
データキュー領域に格納できるデータの数を0にした場合のデータキューの動 作を,図4-1の例を用いて説明する.この図で,タスクAとタスクBは非同期 に実行しているものとする.
• もしタスクAが先にsnd_dtqを呼び出した場合には,タスクBがrcv_dtqを呼 び出すまでタスクAは待ち状態となる.この時タスクAは,データキューへ の送信待ち状態になっている(図4-1 (a)).
• 逆にタスクBが先にrcv_dtqを呼び出した場合には,タスクAがsnd_dtqを呼 び出すまでタスクBは待ち状態となる.この時タスクBは,データキューか らの受信待ち状態になっている(図4-1 (b)).
• タスクAがsnd_dtqを呼び出し,タスクBがrcv_dtqを呼び出した時点で,タ
スクAからタスクBへデータの受渡しが行われる.その後は,両タスクとも 実行できる状態となる.
データキューは,リングバッファで実装することを想定している.
【µITRON3.0仕様との相違】
データキュー機能は,µITRON3.0仕様のリングバッファで実現したメールボッ クスと同等の機能であり,µITRON4.0仕様において新たに導入した機能であ る.
図4-1. データキューによる同期通信 snd_dtq ( dtqid )
送信待ち 状態
タスクA タスクB
rcv_dtq ( dtqid )
(a) snd_dtq が先の場合 (b) rcv_dtq が先の場合 タスクA タスクB
snd_dtq ( dtqid )
rcv_dtq ( dtqid ) 受信待ち
状態
CRE_DTQ データキューの生成(静的API) 【S】
cre_dtq データキューの生成
acre_dtq データキューの生成(ID番号自動割付け)
【静的API】
CRE_DTQ ( ID dtqid, { ATR dtqatr, UINT dtqcnt, VP dtq } ) ;
【C言語API】
ER ercd = cre_dtq ( ID dtqid, T_CDTQ *pk_cdtq ) ; ER_ID dtqid = acre_dtq ( T_CDTQ *pk_cdtq ) ;
【パラメータ】
ID dtqid 生成対象のデータキューのID番号(acre_dtq以
外)
T_CDTQ * pk_cdtq データキュー生成情報を入れたパケットへの
ポインタ(CRE_DTQではパケットの内容を直 接記述する)
pk_cdtqの内容(T_CDTQ型)
ATR dtqatr データキュー属性
UINT dtqcnt データキュー領域の容量(データの個数)
VP dtq データキュー領域の先頭番地
(実装独自に他の情報を追加してもよい)
【リターンパラメータ】
cre_dtqの場合
ER ercd 正常終了(E_OK)またはエラーコード acre_dtqの場合
ER_ID dtqid 生成したデータキューのID番号(正の値)また
はエラーコード
【エラーコード】
E_ID 不正ID番号(dtqidが不正あるいは使用できない;cre_dtq
のみ)
E_NOID ID 番号不足(割付け可能なデータキューID がない;
acre_dtqのみ)
E_NOMEM メモリ不足(データキュー領域などが確保できない)
E_RSATR 予約属性(dtqatrが不正あるいは使用できない)
E_PAR パラメータエラー(pk_cdtq,dtqcnt,dtqが不正)
E_OBJ オブジェクト状態エラー(対象データキューが登録済
み;cre_dtqのみ)
【機能】
dtqidで指定されるID番号を持つデータキューを,pk_cdtqで指定されるデータ
キュー生成情報に基づいて生成する.dtqatrはデータキューの属性,dtqcntは データキュー領域に格納できるデータの個数,dtqはデータキュー領域の先頭 番地である.
CRE_DTQにおいては,dtqidは自動割付け対応整数値パラメータ,dtqatrとdtqcnt
はプリプロセッサ定数式パラメータである.
acre_dtqは,生成するデータキューのID番号をデータキューが登録されていな
いID番号の中から割り付け,割り付けたID番号を返値として返す.
dtqatrには,(TA_TFIFO‖TA_TPRI)の指定ができる.データキューの送信待
ち行列は,TA_TFIFO(=0x00)が指定された場合にはFIFO順,TA_TPRI(=
0x01)が指定された場合にはタスクの優先度順となる.
dtqで指定された番地から,dtqcnt個のデータを格納するのに必要なサイズのメ
モリ領域を,データキュー領域として使用する.TSZ_DTQを用いると,アプ リケーションプログラムから,dtqcnt個のデータを格納するのに必要なサイズ を知ることができる.dtqにNULL(=0)が指定された場合には,必要なサイ ズのメモリ領域をカーネルが確保する.
dtqcntに実装定義の最大値よりも大きい値が指定された場合には,E_PARエ
ラーを返す.dtqcntに0を指定することは可能である.
【スタンダードプロファイル】
スタンダードプロファイルでは,dtqにNULL以外の値が指定された場合の機 能はサポートする必要がない.
【補足説明】
データキューの受信待ち行列は,常にFIFO順となる.また,データキューに 送信されるデータは優先度を持たず,データキュー中のデータの順序もFIFO 順のみをサポートしている.言い換えると,先に送信されたデータから順に受 信されるのが原則である.ただし,snd_dtqとfsnd_dtqを併用した場合には,
snd_dtqで送信待ちしているタスクがあってもfsnd_dtqでデータを送信すること はできるため,fsnd_dtqで送信されたデータがsnd_dtqで送信されたデータを追 い越すことがある.
del_dtq データキューの削除
【C言語API】
ER ercd = del_dtq ( ID dtqid ) ;
【パラメータ】
ID dtqid 削除対象のデータキューのID番号
【リターンパラメータ】
ER ercd 正常終了(E_OK)またはエラーコード
【エラーコード】
E_ID 不正ID番号(dtqidが不正あるいは使用できない)
E_NOEXS オブジェクト未生成(対象データキューが未登録)
【機能】
dtqidで指定されるデータキューを削除する.データキュー領域をカーネルで確
保した場合には,その領域を解放する.
【補足説明】
対象データキューに入っていたデータは破棄される.対象データキューで送信 または受信を待っているタスクがある場合の扱いについては,3.8節を参照す ること.
snd_dtq データキューへの送信 【S】
psnd_dtq データキューへの送信(ポーリング) 【S】
ipsnd_dtq 【S】
tsnd_dtq データキューへの送信(タイムアウトあり) 【S】
【C言語API】
ER ercd = snd_dtq ( ID dtqid, VP_INT data ) ; ER ercd = psnd_dtq ( ID dtqid, VP_INT data ) ; ER ercd = ipsnd_dtq ( ID dtqid, VP_INT data ) ;
ER ercd = tsnd_dtq ( ID dtqid, VP_INT data, TMO tmout ) ;
【パラメータ】
ID dtqid 送信対象のデータキューのID番号
VP_INT data データキューへ送信するデータ
TMO tmout タイムアウト指定(tsnd_dtqのみ)
【リターンパラメータ】
ER ercd 正常終了(E_OK)またはエラーコード
【エラーコード】
E_ID 不正ID番号(dtqidが不正あるいは使用できない)
E_NOEXS オブジェクト未生成(対象データキューが未登録)
E_PAR パラメータエラー(tmoutが不正;tsnd_dtqのみ)
E_RLWAI 待ち状態の強制解除(待ち状態の間に rel_wai を受付;
snd_dtq,tsnd_dtqのみ)
E_TMOUT ポーリング失敗またはタイムアウト(snd_dtq以外)
E_DLT 待ちオブジェクトの削除(待ち状態の間に対象データ
キューが削除;snd_dtq,tsnd_dtqのみ)
【機能】
dtqidで指定されるデータキューに,dataで指定されるデータを送信する.具体 的な処理内容は次の通りである.
対象データキューで受信を待っているタスクがある場合には,受信待ち行列の 先頭のタスクに送信するデータを渡し,そのタスクを待ち解除する.この時,
待ち解除されたタスクに対しては,待ち状態に入ったサービスコールの返値と してE_OKを返し,データキューから受信したデータとしてdataの値を返す.
受信を待っているタスクがない場合は,送信するデータをデータキューの末尾 に入れる.データキュー領域に空きがない場合には,自タスクを送信待ち行列 につなぎ,データキューへの送信待ち状態に移行させる.
他のタスクがすでに送信待ち行列につながっている場合,自タスクを送信待ち 行列につなぐ処理は次のように行う.データキュー属性にTA_TFIFO(=0x00)
が 指 定 さ れ て い る 場 合 に は,自 タ ス ク を 送 信 待 ち 行 列 の 末 尾 に つ な ぐ.