Windows版 iTRONサービスコールの作成 (ランデブポート)
(その5)
ランデブを受け付けるサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
acp_por | タイムアウトなしでランデブを受け付けます。 |
pacp_por | ポーリング方式でランデブを受け付けます。 |
tacp_por | タイムアウト付きでランデブを受け付けます。 |
※ Ver3.0と4.0では関数名は同じですが、引数が異なりますので注意してください。
タイムアウトなしでランデブを受け付けるには以下のサービスコールを使用します。
・Ver3.0の場合
ER acp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
引数 | 説明 |
---|---|
p_rdvno | ランデブ番号を格納する領域のポインタ。 |
msg | 呼び出しメッセージを格納する領域のポインタ。 |
p_cmsgsz | 呼び出しメッセージのサイズを格納する領域のポインタ。 |
porid | ランデブポートID番号。 |
acpptn | 受け付け側選択条件のビットパターン。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のランデブポートID番号。 |
E_NOEXS | 指定したランデブポートID番号は登録されていない。 |
E_PAR | パラメータエラー。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
・Ver4.0の場合
ER_UINT acp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
引数 | 説明 |
---|---|
porid | ランデブポートID番号。 |
acpptn | 受け付け側選択条件のビットパターン。 |
p_rdvno | ランデブ番号を格納する領域のポインタ。 |
msg | 呼び出しメッセージを格納する領域のポインタ。 |
戻り値 | 説明 |
---|---|
E_ID | 範囲外のランデブポートID番号。 |
E_NOEXS | 指定したランデブポートID番号は登録されていない。 |
E_PAR | パラメータエラー。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
その他の正数 | 呼び出しメッセージのサイズ。 |
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブ受け付け (タイムアウトなし).
*
* @param [out] p_rdvno ランデブ番号を格納する領域のポインタ.
* @param [out] msg 呼び出しメッセージを格納する領域のポインタ.
* @param [out] p_cmsgsz 呼び出しメッセージのサイズを格納する領域のポインタ.
* @param [in] porid ランデブポートID番号.
* @param [in] acpptn 受け付け側選択条件のビットパターン.
*
* @retval エラーコード.
*/
ER acp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
{
//! タイムアウトなしでランデブを受け付ける.
return tacp_por( p_rdvno, msg, p_cmsgsz, porid, acpptn, TMO_FEVR );
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブ受け付け (タイムアウトなし).
*
* @param [in] porid ランデブポートID番号.
* @param [in] acpptn 受け付け側選択条件のビットパターン.
* @param [out] p_rdvno ランデブ番号を格納する領域のポインタ.
* @param [out] msg 呼び出しメッセージを格納する領域のポインタ.
*
* @retval 呼び出しメッセージのサイズまたはエラーコード.
*/
ER_UINT acp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
{
//! タイムアウトなしでランデブを受け付ける.
return tacp_por( porid, acpptn, p_rdvno, msg, TMO_FEVR );
}
tacp_por()のタイムアウト設定に TMO_FEVR を指定して呼び出します。
ランデブが成立しない場合は、ランデブが成立するまでタスクをスリープさせます。
ポーリングでランデブを受け付けるには以下のサービスコールを使用します。
・Ver3.0の場合
ER pacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
引数 | 説明 |
---|---|
p_rdvno | ランデブ番号を格納する領域のポインタ。 |
msg | 呼び出しメッセージを格納する領域のポインタ。 |
p_cmsgsz | 呼び出しメッセージのサイズを格納する領域のポインタ。 |
porid | ランデブポートID番号。 |
acpptn | 受け付け側選択条件のビットパターン。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のランデブポートID番号。 |
E_NOEXS | 指定したランデブポートID番号は登録されていない。 |
E_PAR | パラメータエラー。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
E_TMOUT | ランデブが成立しない。 |
・Ver4.0の場合
ER_UINT pacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
引数 | 説明 |
---|---|
porid | ランデブポートID番号。 |
acpptn | 受け付け側選択条件のビットパターン。 |
p_rdvno | ランデブ番号を格納する領域のポインタ。 |
msg | 呼び出しメッセージを格納する領域のポインタ。 |
戻り値 | 説明 |
---|---|
E_ID | 範囲外のランデブポートID番号。 |
E_NOEXS | 指定したランデブポートID番号は登録されていない。 |
E_PAR | パラメータエラー。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
E_TMOUT | ランデブが成立しない。 |
その他の正数 | 呼び出しメッセージのサイズ。 |
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブ受け付け (ポーリング).
*
* @param [out] p_rdvno ランデブ番号を格納する領域のポインタ.
* @param [out] msg 呼び出しメッセージを格納する領域のポインタ.
* @param [out] p_cmsgsz 呼び出しメッセージのサイズを格納する領域のポインタ.
* @param [in] porid ランデブポートID番号.
* @param [in] acpptn 受け付け側選択条件のビットパターン.
*
* @retval エラーコード.
*/
ER pacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn )
{
//! 呼び出し待ちなしでランデブを受け付ける.
return tacp_por( p_rdvno, msg, p_cmsgsz, porid, acpptn, TMO_POL );
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブ受け付け (ポーリング).
*
* @param [in] porid ランデブポートID番号.
* @param [in] acpptn 受け付け側選択条件のビットパターン.
* @param [out] p_rdvno ランデブ番号を格納する領域のポインタ.
* @param [out] msg 呼び出しメッセージを格納する領域のポインタ.
*
* @retval 呼び出しメッセージのサイズまたはエラーコード.
*/
ER_UINT pacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg )
{
//! 呼び出し待ちなしでランデブを受け付ける.
return tacp_por( porid, acpptn, p_rdvno, msg, TMO_POL );
}
tacp_por()のタイムアウト設定に TMO_POL を指定して呼び出します。
ランデブが成立しない場合は、タスクをスリープさせずに戻り値をE_TMOUTとしてすぐにサービスコールから戻ります。
タイムアウト付きでランデブを受け付けるには以下のサービスコールを使用します。
・Ver3.0の場合
ER tacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn, TMO tmout )
引数 | 説明 |
---|---|
p_rdvno | ランデブ番号を格納する領域のポインタ。 |
msg | 呼び出しメッセージを格納する領域のポインタ。 |
p_cmsgsz | 呼び出しメッセージのサイズを格納する領域のポインタ。 |
porid | ランデブポートID番号。 |
acpptn | 受け付け側選択条件のビットパターン。 |
tmout |
タイムアウトの設定値。
|
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のランデブポートID番号。 |
E_NOEXS | 指定したランデブポートID番号は登録されていない。 |
E_PAR | パラメータエラー。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
E_TMOUT | ランデブが成立しない。 |
・Ver4.0の場合
ER_UINT tacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg, TMO tmout )
引数 | 説明 |
---|---|
porid | ランデブポートID番号。 |
acpptn | 受け付け側選択条件のビットパターン。 |
p_rdvno | ランデブ番号を格納する領域のポインタ。 |
msg | 呼び出しメッセージを格納する領域のポインタ。 |
tmout |
タイムアウトの設定値。
|
戻り値 | 説明 |
---|---|
E_ID | 範囲外のランデブポートID番号。 |
E_NOEXS | 指定したランデブポートID番号は登録されていない。 |
E_PAR | パラメータエラー。 |
E_CTX | 非コンテキスト・タスクからの呼び出し。 |
E_TMOUT | ランデブが成立しない。 |
その他の正数 | 応答メッセージのサイズ。 |
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブ受け付け (タイムアウトあり).
*
* @param [out] p_rdvno ランデブ番号を格納する領域のポインタ.
* @param [out] msg 呼び出しメッセージを格納する領域のポインタ.
* @param [out] p_cmsgsz 呼び出しメッセージのサイズを格納する領域のポインタ.
* @param [in] porid ランデブポートID番号.
* @param [in] acpptn 受け付け側選択条件のビットパターン.
* @param [in] tmout タイムアウト設定.
*
* @retval エラーコード.
*/
ER tacp_por( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn, TMO tmout )
{
ER ercd;
wi_CommonLock();
//! ランデブを受け付ける.
ercd = wi_AcceptRendPort( porid, acpptn, p_rdvno, msg, p_cmsgsz, tmout );
wi_CommonUnlock();
return ercd;
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブ受け付け (タイムアウトあり).
*
* @param [in] porid ランデブポートID番号.
* @param [in] acpptn 受け付け側選択条件のビットパターン.
* @param [out] p_rdvno ランデブ番号を格納する領域のポインタ.
* @param [out] msg 呼び出しメッセージを格納する領域のポインタ.
* @param [in] tmout タイムアウト設定.
*
* @retval 呼び出しメッセージのサイズまたはエラーコード.
*/
ER_UINT tacp_por( ID porid, RDVPTN acpptn, RDVNO *p_rdvno, VP msg, TMO tmout )
{
ER ercd;
INT size;
wi_CommonLock();
//! ランデブを受け付ける.
ercd = wi_AcceptRendPort( porid, acpptn, p_rdvno, msg, &size, tmout );
if( ercd == E_OK ){
ercd = size;
}
wi_CommonUnlock();
return ercd;
}
指定したランデブポートID番号のランデブを受け付けます。
ランデブが成立しない場合は、ランデブが成立するか、または、タイムアウトで設定した時間が経過するまでタスクをスリープさせます。
ランデブの受け付け関数
ランデブの受け付け関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief ランデブ受け付け.
*
* @param [in] id ランデブポートID番号.
* @param [in] ptn 受け付け側選択条件のビットパターン.
* @param [out] no ランデブ番号を格納する領域のポインタ.
* @param [out] msg 呼び出しメッセージを格納する領域のポインタ.
* @param [out] size 呼び出しメッセージのサイズを格納する領域のポインタ.
* @param [in] tmout タイムアウト設定.
*
* @retval エラーコード.
*/
ER wi_AcceptRendPort( INT id, UINT ptn, INT *no, VP msg, INT *size, TMO tmout )
{
ER ercd;
WIPOROBJ *p;
WITSKOBJ *cal_tsk,*acp_tsk;
//! 引数が不正な場合はエラーにする.
if( !no || !size ){
return E_PAR;
}
//! ランデブポートIDのオブジェクトを取得する.
p = (WIPOROBJ *)wi_FindObject( id, TMAX_MAXPOR, PortList, &ercd );
if( !p ){
return ercd;
}
//! 自タスクのタスクコンテキストを取り出す.
acp_tsk = wi_GetTaskObject( TSK_SELF );
if( !acp_tsk ){
return E_CTX;
}
acp_tsk->Param[0] = (VP)ptn;
acp_tsk->Param[1] = (VP)msg;
acp_tsk->Param[2] = (VP)0;
//! ランデブ呼び出しをしているタスクに対してランデブが成立するかどうかを調べる.
cal_tsk = SatisfyRendezvous( (WITSKOBJ *)(p->CalWaitQue), ptn );
if( !cal_tsk ){
//! ランデブが成立するまでタスクをスリープさせる.
ercd = wi_TaskWait( id, TTW_ACP, tmout, p->Attribute, &(p->AcpWaitQue) );
if( ercd != E_OK ){
return ercd;
}
*size = (INT)acp_tsk->Param[2];
*no = (INT)acp_tsk->Param[3];
}else{
//! 成立したランデブを登録する.
ercd = CreateRdv( cal_tsk->Hdr.Id, p->MaxRepMsg );
if( ercd != E_OK ){
return ercd;
}
//! ランデブ番号を戻り値にセットする.
*no = RdvSeqNo;
//! 呼び出しメッセージを呼び出し側タスクからコピーする.
if( cal_tsk->Param[1] && (INT)cal_tsk->Param[2] > 0 ){
memcpy( msg, cal_tsk->Param[1], (INT)cal_tsk->Param[2] );
*size = (INT)cal_tsk->Param[2];
}else{
*size = 0;
}
//! 呼び出し側タスクを待ち行列から削除する.
p->CalWaitQue = wi_DelWaitTaskList( cal_tsk->Hdr.Id, p->CalWaitQue );
//! 呼び出し側タスクのイベント待ち状態を「ランデブ終了待ち」にする.
cal_tsk->EventType = TTW_RDV;
cal_tsk->WaitId = RdvSeqNo;
cal_tsk->QueLink = NULL;
ercd = E_OK;
}
return ercd;
}
ランデブの受け付け関数は以下のような処理を行います。
- 引数で指定されたランデブポートID番号に該当するランデブポート・オブジェクトを取り出します。
- 非タスクコンテキストからの呼び出しの場合はエラー終了します。
- ランデブ成立待ちをしているタスクがある場合、ランデブ条件ビットパターンをチェックして、ランデブが成立するかどうかを調べます。
- ランデブが成立しない場合、タスクをスリープさせます。(以降ランデブ成立のチェックは、ランデブ呼び出し側で行います。)
- ランデブが成立した場合、以下の処理を行います。
- 『ランデブ・オブジェクト』を生成します。
- ランデブ呼び出しタスクからランデブ呼び出しメッセージをコピーします。
- ランデブ呼び出しタスクを待ち行列から削除します。
- ランデブ呼び出しタスクのイベント待ち状態を「ランデブ成立待ち」から「ランデブ終了待ち」に変更します。