Windows版 iTRONサービスコールの作成 (ランデブポート)
(その6)
ランデブが成立した呼び出し側タスクと新たに回送先のランデブ受付け側タスクでランデブを成立させます。
ランデブを回送すると新たにランデブ・オブジェクトを生成するので、成立していたランデブのオブジェクトは消去されます。
ランデブを回送するサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
fwd_por | ランデブを他のランデブポートに回送します。 |
ランデブを他のランデブポートに回送するには以下のサービスコールを使用します。
・Ver3.0の場合
ER fwd_por( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz )
・Ver4.0の場合
ER fwd_por( ID porid, RDVPTN calptn, RDVNO rdvno, VP msg, UINT cmsgsz )
引数 | 説明 |
---|---|
porid | ランデブポートID番号。 |
calptn | 受け付け側選択条件のビットパターン。 |
rdvno | ランデブ番号。 |
msg | 呼び出しメッセージのポインタ。 |
cmsgsz | 呼び出しメッセージのサイズ。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のランデブポートID番号。 |
E_NOEXS | 指定したランデブポートID番号は登録されていない。 |
E_PAR | パラメータエラー。 |
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブの回送
*
* @param [in] porid ランデブポートID番号.
* @param [in] calptn 受け付け側選択条件のビットパターン.
* @param [in] rdvno ランデブ番号.
* @param [in] msg 呼び出しメッセージのポインタ.
* @param [in] cmsgsz 呼び出しメッセージのサイズ.
*
* @retval エラーコード.
*/
ER fwd_por( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz )
{
ER ercd;
wi_CommonLock();
//! ランデブを他のランデブ・ポートに回送する.
ercd = wi_FowardRendPort( porid, calptn, rdvno, msg, cmsgsz );
wi_CommonUnlock();
return ercd;
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブの回送
*
* @param [in] porid ランデブポートID番号.
* @param [in] calptn 受け付け側選択条件のビットパターン.
* @param [in] rdvno ランデブ番号.
* @param [in] msg 呼び出しメッセージのポインタ.
* @param [in] cmsgsz 呼び出しメッセージのサイズ.
*
* @retval エラーコード.
*/
ER fwd_por( ID porid, RDVPTN calptn, RDVNO rdvno, VP msg, UINT cmsgsz )
{
ER ercd;
wi_CommonLock();
//! ランデブを他のランデブ・ポートに回送する.
ercd = wi_FowardRendPort( porid, calptn, rdvno, msg, cmsgsz );
wi_CommonUnlock();
return ercd;
}
ランデブの回送関数
ランデブの回送関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief ランデブの回送
*
* @param [in] id ランデブポートID番号.
* @param [in] ptn 受け付け側選択条件のビットパターン.
* @param [in] no ランデブ番号.
* @param [in] msg 呼び出しメッセージのポインタ.
* @param [in] size 呼び出しメッセージのサイズ.
*
* @retval エラーコード.
*/
ER wi_FowardRendPort( INT id, UINT ptn, INT no, VP msg, INT size )
{
ER ercd;
WIPOROBJ *p;
WITSKOBJ *acp_tsk,*rdv_tsk;
WIRDVOBJ *rdv;
//! ランデブポートIDのオブジェクトを取得する.
p = (WIPOROBJ *)wi_FindObject( id, TMAX_MAXPOR, PortList, &ercd );
if( !p ){
return ercd;
}
//! ランデブ番号のオブジェクトを取得する.
rdv = (WIRDVOBJ *)wi_FindObject( no, TMAX_MAXRDV, RdvList, &ercd );
if( !rdv ){
return E_OBJ;
}
//! ランデブ終了待ちをしているタスクのコンテキストを取得する.
rdv_tsk = wi_GetTaskObject( rdv->TaskId );
if( !rdv_tsk ){
return E_OBJ;
}
//! ランデブ受付待ちをしているタスクに対してランデブが成立するかどうかを調べる.
acp_tsk = SatisfyRendezvous( (WITSKOBJ *)(p->AcpWaitQue), ptn );
if( !acp_tsk ){
//! ランデブ終了待ちタスクのイベント待ち状態を「ランデブ成立待ち」にする.
rdv_tsk->EventType = TTW_CAL;
rdv_tsk->WaitId = p->Hdr.Id;
//! ランデブ呼び出し待ち行列にランデブ終了待ちタスクを追加する.
p->CalWaitQue = wi_AddWaitTaskList( rdv->TaskId, p->Attribute, p->CalWaitQue );
}else{
//! 成立したランデブを登録する.
ercd = CreateRdv( rdv_tsk->Hdr.Id, p->MaxRepMsg );
if( ercd != E_OK ){
return ercd;
}
acp_tsk->Param[2] = 0;
acp_tsk->Param[3] = (VP)RdvSeqNo;
//! ランデブ受付タスクにランデブ回送メッセージをコピーする.
if( acp_tsk->Param[1] && msg && size > 0 ){
memcpy( acp_tsk->Param[1], msg, size );
acp_tsk->Param[2] = (VP)size;
}
//! ランデブ受付待ちをしているタスクを起床する.
wi_TaskWakeup( acp_tsk->Hdr.Id, TTW_ACP, &(p->AcpWaitQue) );
}
//! ランデブ・オブジェクトを削除する.
DeleteRdv( no );
return E_OK;
}
ランデブの受け付け関数は以下のような処理を行います。
- 引数で指定されたランデブポートID番号に該当するランデブポート・オブジェクトを取り出します。
- 引数で指定されたランデブ番号に該当するランデブ・オブジェクトを取り出します。
- ランデブ受付け待ちをしているタスクがある場合、ランデブ条件ビットパターンをチェックして、ランデブが成立するかどうかを調べます。
- ランデブが成立しない場合、ランデブ終了待ちをしているタスクのイベント待ち状態を「ランデブ終了待ち」から「ランデブ成立待ち」にして、引数で指定されたランデブ・ポートの呼び出し待ち行列に追加します。
- ランデブが成立した場合、以下の処理を行います。
- 『ランデブ・オブジェクト』を生成します。
- ランデブ受付けタスクに引数で指定されたメッセージをコピーします。
- ランデブ受付けタスクを起床します。
- 引数で指定されたランデブ番号に該当するランデブ・オブジェクトを削除します。