第 4 章 µITRON4.0 仕様の機能 81
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)
が指 定され ている 場合 には,自タ スクを 送信 待ち行 列の 末尾に つなぐ.