• 検索結果がありません。

メールボックス

ドキュメント内 mitron402.book (ページ 181-192)

第 4 章 µITRON4.0 仕様の機能 81

4.4 同期・通信機能

4.4.4 メールボックス

メールボックスは,共有メモリ上に置かれたメッセージを受渡しすることによ り,同期と通信を行うためのオブジェクトである.メールボックス機能には,

メールボックスを生成/削除する機能,メールボックスに対してメッセージを 送信/受信する機能,メールボックスの状態を参照する機能が含まれる.メー ルボックスは ID番号で識別されるオブジェクトである.メールボックスの ID 番号をメールボックス IDと呼ぶ.

メールボックスは,送信されたメッセージを入れるためのメッセージキュー と,メッセージの受信を待つタスクの待ち行列を持つ.メッセージを送信する 側(イベントを知らせる側)では,送信したいメッセージをメッセージキュー に入れる.一方,メッセージを受信する側(イベントを待つ側)では,メッ セージキューに入っているメッセージを一つ取り出す.メッセージキューに メッセージが入っていない場合は,次にメッセージが送られてくるまでメール ボックスからの受信待ち状態になる.メールボックスからの受信待ち状態に なったタスクは,そのメールボックスの待ち行列につながれる.

メールボックスによって実際に送受信されるのは,送信側と受信側で共有して いるメモリ上に置かれたメッセージの先頭番地のみである.すなわち,送受信 されるメッセージの内容のコピーは行わない.

カーネルは,メッセージキューに入っているメッセージを,リンクリストによ り管理する.アプリケーションプログラムは,送信するメッセージの先頭に,

カーネルがリンクリストに用いるための領域を確保しなければならない.この 領域をメッセージヘッダと呼ぶ.また,メッセージヘッダと,それに続くアプ リケーションがメッセージを入れるための領域をあわせて,メッセージパケッ トと呼ぶ.メールボックスへメッセージを送信するサービスコールは,メッ セージパケットの先頭番地をパラメータとする.また,メールボックスから メッセージを受信するサービスコールは,メッセージパケットの先頭番地をリ ターンパラメータとして返す.メッセージキューをメッセージの優先度順にす る場合には,メッセージの優先度を入れるための領域も,メッセージヘッダ中 に持つ必要がある.

カーネルは,メッセージキューに入っている(ないしは,入れようとしてい る)メッセージのメッセージヘッダ(メッセージ優先度のための領域を除く)

の内容を書き換える.一方,アプリケーションは,メッセージキューに入って いるメッセージのメッセージヘッダ(メッセージ優先度のための領域を含む)

の内容を書き換えてはならない.アプリケーションによってメッセージヘッダ の内容が書き換えられた場合の振舞いは未定義である.この規定は,アプリ ケーションプログラムがメッセージヘッダの内容を直接書き換えた場合に加 えて,メッセージヘッダの番地をカーネルに渡し,カーネルにメッセージヘッ ダの内容を書き換えさせた場合にも適用される.したがって,すでにメッセー ジキューに入っているメッセージを再度メールボックスに送信した場合の振 舞いは未定義となる.

メッセージヘッダのデータ型として,次のデータ型を定義する.

T_MSG メールボックスのメッセージヘッダ

T_MSG_PRI メールボックスの優先度付きメッセージヘッダ

T_MSG型の定義やサイズは,実装定義である.それに対して T_MSG_PRI型 は, T_MSG型を用いて次のように定義する.

typedef struct t_msg_pri {

T_MSG msgque ; /* メッセージヘッダ  */

PRI msgpri ; /* メッセージ優先度  */

} T_MSG_PRI ;

メールボックス機能に関連して,次のカーネル構成マクロを定義する.

SIZE mprihdsz = TSZ_MPRIHD ( PRI maxmpri )

送信されるメッセージの優先度の最大値が maxmpriのメールボックス に必要な優先度別メッセージキューヘッダ領域のサイズ(バイト数)

メールボックス生成情報およびメールボックス状態のパケット形式として,次 のデータ型を定義する.

typedef struct t_cmbx {

ATR mbxatr ; /* メールボックス属性  */

PRI maxmpri ; /* 送信されるメッセージの優先度の最

大値  */

VP mprihd ; /* 優先度別のメッセージキューヘッダ

領域の先頭番地  */

/* 実装独自に他のフィールドを追加してもよい  */

} T_CMBX ;

typedef struct t_rmbx {

ID wtskid ; /* メールボックスの待ち行列の先頭の

タスクの ID番号  */

T_MSG * pk_msg ; /* メッセージキューの先頭のメッセー ジパケットの先頭番地  */

/* 実装独自に他のフィールドを追加してもよい  */

} T_RMBX ;

メールボックス機能の各サービスコールの機能コードは次の通りである.

TFN_CRE_MBX –0x3d cre_mbxの機能コード TFN_ACRE_MBX –0xc5 acre_mbxの機能コード TFN_DEL_MBX –0x3e del_mbxの機能コード TFN_SND_MBX –0x3f snd_mbxの機能コード TFN_RCV_MBX –0x41 rcv_mbxの機能コード TFN_PRCV_MBX –0x42 prcv_mbxの機能コード TFN_TRCV_MBX –0x43 trcv_mbxの機能コード TFN_REF_MBX –0x44 ref_mbxの機能コード

【スタンダードプロファイル】

スタンダードプロファイルでは,メールボックスを動的に生成/削除する機能

( cre_mbx, acre_mbx, del_mbx),メールボックスの状態を参照する機能

( ref_mbx)を除いて,メールボックス機能をサポートしなければならない.

スタンダードプロファイルでは, TSZ_MPRIHDを定義する必要はない.

【補足説明】

メールボックス機能では,メッセージヘッダの領域をアプリケーションプログ ラムで確保することとしているため,メッセージキューに入れることができる メッセージの数には上限がない.また,メッセージを送信するサービスコール で待ち状態になることもない.

アプリケーションプログラムをメッセージヘッダの定義やサイズが異なる カーネルへも移植可能とするためには,アプリケーションで用いるメッセージ パケットを C言語の構造体として定義し,その先頭に T_MSG型ないしは

T_MSG_PRI型のフィールドを確保すればよい.また,メッセージに優先度を

設定する場合には,メッセージパケットの先頭に確保した T_MSG_PRI型の フィールド中の msgpriフィールドに代入する.メッセージヘッダのサイズを 知る必要がある場合には, sizeof ( T_MSG )ないしは sizeof ( T_MSG_PRI )を 用いることができる.

メッセージパケットとしては,固定長メモリプールまたは可変長メモリプール から動的に確保したメモリブロックを用いることも,静的に確保した領域を用 いることも可能である.一般的な使い方としては,送信側のタスクがメモリ プールからメモリブロックを確保し,それをメッセージパケットとして送信 し,受信側のタスクはメッセージの内容を取り出した後にそのメモリブロック を直接メモリプールに返却するという手順をとることが多い.

【 µITRON3.0仕様との相違】

メールボックスの実現方法を,リンクリストを使う方法に限定した.

CRE_MBX

メールボックスの生成(静的 API) 【 S】

cre_mbx

メールボックスの生成

acre_mbx

メールボックスの生成( ID番号自動割付け)

【静的 API】

CRE_MBX ( ID mbxid, { ATR mbxatr, PRI maxmpri, VP mprihd } ) ;

【 C言語 API】

ER ercd = cre_mbx ( ID mbxid, T_CMBX *pk_cmbx ) ; ER_ID mbxid = acre_mbx ( T_CMBX *pk_cmbx ) ;

【パラメータ】

ID mbxid 生成対象のメールボックスの ID 番号

( acre_mbx以外)

T_CMBX * pk_cmbx メールボックス生成情報を入れたパケットへ のポインタ( CRE_MBXではパケットの内容を 直接記述する)

pk_cmbxの内容( T_CMBX型)

ATR mbxatr メールボックス属性

PRI maxmpri 送信されるメッセージの優先度の最大値

VP mprihd 優先度別のメッセージキューヘッダ領域の先

頭番地

(実装独自に他の情報を追加してもよい)

【リターンパラメータ】

cre_mbxの場合

ER ercd 正常終了( E_OK)またはエラーコード acre_mbxの場合

ER_ID mbxid 生成したメールボックスの ID番号(正の値)ま

たはエラーコード

【エラーコード】

E_ID 不正 ID 番号( mbxid が不正あるいは使用できない;

cre_mbxのみ)

E_NOID ID 番号不足(割付け可能なメールボックス IDがない;

acre_mbxのみ)

E_NOMEM メモリ不足(優先度別のメッセージキューヘッダ領域な

どが確保できない)

E_RSATR 予約属性( mbxatrが不正あるいは使用できない)

E_PAR パラメータエラー( pk_cmbx, maxmpri, mprihd が 不正)

E_OBJ オブジェクト状態エラー(対象メールボックスが登録済 み; cre_mbxのみ)

【機能】

mbxidで指定される ID番号を持つメールボックスを, pk_cmbxで指定される メールボックス生成情報に基づいて生成する. mbxatrはメールボックスの属

性, maxmpriはメールボックスに送信されるメッセージの優先度の最大値,

mprihdはメールボックスの優先度別のメッセージキューヘッダ領域の先頭番

地である. maxmpriと mprihdは, mbxatrに TA_MPRI(= 0x02)が指定さ れた場合にのみ有効である.

CRE_MBXにおいては, mbxidは自動割付け対応整数値パラメータ, mbxatr と maxmpriはプリプロセッサ定数式パラメータである.

acre_mbxは,生成するメールボックスの ID番号をメールボックスが登録され

ていない ID番号の中から割り付け,割り付けた ID番号を返値として返す.

mbxatrには,(( TA_TFIFO‖ TA_TPRI)|( TA_MFIFO‖ TA_MPRI))の指 定ができる.メールボックスの待ち行列は, TA_TFIFO(= 0x00)が指定され た場合には FIFO順, TA_TPRI(= 0x01)が指定された場合にはタスクの優先 度順となる.また,メールボックスのメッセージキューは, TA_MFIFO(=

0x00)が指定された場合には FIFO順, TA_MPRI(= 0x02)が指定された場合

にはメッセージの優先度順となる.

mbxatrに TA_MPRIが指定された場合, mprihdで指定された番地から,送信 されるメッセージの優先度の最大値が maxmpriの場合に必要なサイズのメモ リ 領域 を,優 先 度 別 の メ ッ セー ジ キ ュ ー ヘ ッ ダ領 域 と し て 使 用 する.

TSZ_MPRIHDを用いると,アプリケーションプログラムから,送信されるメッ

セージの優先度の最大値が maxmpriの場合に必要なサイズを知ることができ る. mprihdに NULL(= 0)が指定された場合には,必要なサイズのメモリ領 域をカーネルが確保する.

maxmpriに 0が指定された場合や,メッセージ優先度の最大値( TMAX_MPRI)

よりも大きい値が指定された場合には, E_PARエラーを返す.

【スタンダードプロファイル】

スタンダードプロファイルでは, mprihdに NULL以外の値が指定された場合 の機能はサポートする必要がない.

【補足説明】

メールボックスの優先度別のメッセージキューヘッダ領域を活用し,メッセー ジのキューを優先度毎に用意する場合には,次のような配慮が必要である.

メッセージのキューを優先度毎に用意する方法は,メッセージ優先度の段階数 が少ない場合には有効な方法であるが,メッセージ優先度の段階数が多い場合 には,メモリ使用量が大きくなるために現実的ではない.そこで,メッセージ 優先度の段階数が多い場合にも対応するために,メッセージ優先度の段階数に よってキューの構造を変えるといった工夫が必要になる.例えば,送信される

ドキュメント内 mitron402.book (ページ 181-192)