優先度データキューは、1ワードのデータをメッセージとして、データの優先度順で送受信するための同期・通信カーネルオブジェクトである。より大きいサイズのメッセージを送受信したい場合には、メッセージを置いたメモリ領域へのポインタを1ワードのデータとして送受信する方法がある。優先度データキューは,優先度データキューIDと呼ぶID番号によって識別する [:toppers3-tag:`NGKI1791`]。
.. todo::
アプリケーション開発者は tPriorityDataqueue セルタイプのセルを生成することにより、優先度データキューを生成することができます。次の例では MyPriorityDataqueue
という名前の優先度データキューセルを生成し、 MyCell
の eTaskBody
をメインルーチンとして結合しています。
celltype tMyCellType {
call sPriorityDataqueue cPriorityDataqueue;
};
cell tMyCellType MyCell {
cPriorityDataqueue = MyPriorityDataqueue.ePriorityDataqueue;
};
cell tPriorityDataqueue MyPriorityDataqueue {
attribute = C_EXP("TA_NULL");
count = 1;
maxDataPriority = C_EXP("TMAX_DPRI");
pdqmb = C_EXP( "NULL" );
};
void eTaskBody_main(CELLIDX idx)
{
CELLCB *p_cellcb = GET_CELLCB(idx);
// ...
}
tPriorityDataqueue が提供する :tecs:entry:`~t::ePriorityDataqueue` という名前の受け口を利用することにより、優先度データキューの制御及び状態の取得を行うことができます。
cell tPriorityDataqueue MyPriorityDataqueue {};
celltype tMyAnotherCellType {
call sPriorityDataqueue cPriorityDataqueue;
};
cell tMyAnotherCellType MyAnotherCell {
cPriorityDataqueue = MyPriorityDataqueue.ePriorityDataqueue;
};
// 優先度データキューの送信
intptr_t data;
PRI dataPriority;
cPriorityDataqueue_send( data, dataPriority );
// 優先度データキューの受信
intptr_t *p_data;
PRI *p_dataPriority;
cPriorityDataqueue_receive( p_data, p_dataPriority );
なお、非タスクコンテキスト内では、:tecs:entry:`~tPriorityDataqueue::ePriorityDataqueue` の代わりに :tecs:entry:`~tPriorityDataqueue::eiPriorityDataqueue` を使用する必要があります。
.. tecs:celltype:: tPriorityDataqueue 優先度データキューの生成、制御及び状態の取得を行うコンポーネントです。 本コンポーネントは `CRE_PDQ` 静的API [:toppers3-tag:`NGKI1800`] により優先度データキューの生成を行います。静的APIの引数の値には、一部を除き属性値が用いられます。 .. tecs:attr:: ID id = C_EXP("PDQID_$id$"); 優先度データキューのID番号の識別子 (詳しくは :ref:`asp3tecs-id` を参照) を `C_EXP` で囲んで指定します (省略可能)。 .. tecs:attr:: ATR attribute 優先度データキュー属性 [:toppers3-tag:`NGKI1795`] を `C_EXP` で囲んで指定します (省略可能)。 .. c:macro:: TA_NULL デフォルト値(FIFO待ち)。 .. c:macro:: TA_TPRI 送信待ち行列をタスクの優先度順にする。 .. tecs:attr:: uint32_t count = 1; 優先度データキューの容量。 .. tecs:attr:: PRI maxDataPriority 優先度データキューに送信できるデータ優先度の最大値。 .. tecs:attr:: void *pdqmb = C_EXP("NULL"); 優先度データキュー管理領域の先頭番地。 .. tecs:entry:: sPriorityDataqueue ePriorityDataqueue 優先度データキューの制御及び状態の取得を行うための受け口です。 .. tecs:entry:: siPriorityDataqueue eiPriorityDataqueue 優先度データキューの制御を行うための受け口です (非タスクコンテキスト用)。
.. tecs:signature:: sPriorityDataqueue 優先度データキューの制御、及び状態の取得を行うためのシグニチャです。 .. tecs:sigfunction:: ER send([in] intptr_t data, [in] PRI dataPriority) 対象優先度データキューに、dataで指定したデータを、dataPriorityで指定した優先度で送信します。対象優先度データキューの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。 この関数は `snd_pdq` サービスコール [:toppers3-tag:`NGKI1855`] のラッパーです。 :param data: 送信データ。 :param dataPriority: 送信データの優先度。 :return: 正常終了 (`E_OK`) またはエラーコード。 .. tecs:sigfunction:: ER sendPolling([in] intptr_t data, [in] PRI dataPriority) 対象優先度データキューに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(ポーリング)。対象優先度データキューの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。 この関数は `psnd_pdq` サービスコール [:toppers3-tag:`NGKI3537`] のラッパーです。 :param data: 送信データ。 :param dataPriority: 送信データの優先度。 :return: 正常終了 (`E_OK`) またはエラーコード。 .. tecs:sigfunction:: ER sendTimeout([in] intptr_t data, [in] PRI dataPriority, [in] TMO timeout) 対象優先度データキューに、dataで指定したデータを、dataPriorityで指定した優先度で送信します(タイムアウト付き)。対象優先度データキューの受信待ち行列にタスクが存在する場合には、受信待ち行列の先頭のタスクが、dataで指定したデータを受信し、待ち解除されます。待ち解除されたタスクに待ち状態となったサービスコールからE_OKが返ります。 この関数は `tsnd_pdq` サービスコール [:toppers3-tag:`NGKI1858`] のラッパーです。 :param data: 送信データ。 :param dataPriority: 送信データの優先度。 :param timeout: タイムアウト時間。 :return: 正常終了 (`E_OK`) またはエラーコード。 .. tecs:sigfunction:: ER receive([out] intptr_t *p_data, [in] PRI *p_dataPriority) 対象優先度データキューからデータを受信します。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。 この関数は `rcv_pdq` サービスコール [:toppers3-tag:`NGKI1877`] のラッパーです。 :param p_data: 受信データを入れるメモリ領域へのポインタ。 :param p_dataPriority: 受信データの優先度を入れるメモリ領域へのポインタ。 :return: 正常終了 (`E_OK`) またはエラーコード。 .. tecs:sigfunction:: ER receivePolling([out] intptr_t *p_data, [in] PRI *p_dataPriority) 対象優先度データキューからデータを受信します(ポーリング)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。 この関数は `prcv_pdq` サービスコール [:toppers3-tag:`NGKI1878`] のラッパーです。 :param p_data: 受信データを入れるメモリ領域へのポインタ。 :param p_dataPriority: 受信データの優先度を入れるメモリ領域へのポインタ。 :return: 正常終了 (`E_OK`) またはエラーコード。 .. tecs:sigfunction:: ER receiveTimeout([out] intptr_t *p_data, [in] PRI *p_dataPriority, [in] TMO timeout) 対象優先度データキューからデータを受信します(タイムアウト付き)。データの受信に成功した場合、受信したデータはp_dataが指すメモリ領域に、その優先度はp_dataPriorityが指すメモリ領域に返されます。 この関数は `trcv_pdq` サービスコール [:toppers3-tag:`NGKI1879`] のラッパーです。 :param p_data: 受信データを入れるメモリ領域へのポインタ。 :param p_dataPriority: 受信データの優先度を入れるメモリ領域へのポインタ。 :param timeout: タイムアウト時間。 :return: 正常終了 (`E_OK`) またはエラーコード。 .. tecs:sigfunction:: ER initialize(void); 対象優先度データキューを再初期化します。対象優先度データキューの優先度データキュー管理領域は、格納されているデータがない状態に初期化されます。 この関数は `ini_pdq` サービスコール [:toppers3-tag:`NGKI1902`] のラッパーです。 :return: 正常終了 (`E_OK`) またはエラーコード。 .. tecs:sigfunction:: ER refer([out] T_RSEM *pk_priorityDataqueueStatus); 優先度データキューの現在状態を参照します。 この関数は `ref_pdq` サービスコール [:toppers3-tag:`NGKI1911`] のラッパーです。 :param pk_priorityDataqueueStatus: 優先度データキューの現在状態を入れるメモリ領域へのポインタ。 :return: 正常終了 (`E_OK`) またはエラーコード。
.. tecs:signature:: siPriorityDataqueue 優先度データキューの制御を行うためのシグニチャです (非タスクコンテキスト用)。 .. tecs:sigfunction:: ER sendPolling([in]intptr_t data, [in] PRI dataPriority); この関数は `snd_pdq` サービスコール [:toppers3-tag:`NGKI1855`] のラッパーです。 :return: 正常終了 (`E_OK`) またはエラーコード。
tPriorityDataqueue による優先度データキューの生成は、以下に示しているようなファクトリ記述により静的 API 記述を生成することで実現されています。
factory {
write( "tecsgen.cfg", "CRE_PDQ( %s, { %s, %s, %s, %s} );",
id, attribute, count, maxDataPriority, pdqmb);
};
最初の MyPriorityDataqueue
を用いた例の場合、以下のような静的API記述が生成されます。
CRE_PDQ( PDQID_tPriorityDataqueue_MyPriorityDataqueue, { TA_NULL, 1, TMAX_DPRI, NULL });
tPriorityDataqueue が持つ属性は、 :tecs:attr:`~tPriorityDataqueue::id` を除き実行時にはすべて未使用である為、[omit]
指定を行うことでこれらの属性値へのメモリ割り当てが行われないようにしています。
:tecs:entry:`~tPriorityDataqueue::ePriorityDataqueue` 及び :tecs:entry:`~tPriorityDataqueue::eiPriorityDataqueue` に対する呼出しは、以下に示すような受け口関数により TOPPERS/ASP3 カーネルのサービスコールへの呼出しに変換されます。
Inline ER
ePriorityDataqueue_send(CELLIDX idx)
{
CELLCB *p_cellcb = GET_CELLCB(idx);
return(snd_pdq(ATTR_id));
}