Windows版 iTRONサービスコールの作成 (ランデブポート)
(その7)
ランデブの終了を呼び出すことで、ランデブ呼び出しを行ったタスクを起床できます。
ランデブ・オブジェクトは、ランデブノ終了で削除されます。
ランデブを終了するサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
rpl_rdv | ランデブの終了を通知します。 |
ランデブの終了を通知するには以下のサービスコールを使用します。
・Ver3.0の場合
ER rpl_rdv( RNO rdvno, VP msg, INT cmsgsz )
・Ver4.0の場合
ER rpl_rdv( RDVNO rdvno, VP msg, UINT cmsgsz )
引数 | 説明 |
---|---|
rdvno | ランデブ番号。 |
msg | 返答メッセージのポインタ。 |
cmsgsz | 返答メッセージのサイズ。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_OBJ | 指定したランデブ番号は登録されていない。 |
E_PAR | パラメータエラー。 |
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブの終了.
*
* @param [in] rdvno ランデブ番号.
* @param [in] msg 返答メッセージのポインタ.
* @param [in] cmsgsz 返答メッセージのサイズ.
*
* @retval エラーコード.
*/
ER rpl_rdv( RNO rdvno, VP msg, INT cmsgsz )
{
ER ercd;
wi_CommonLock();
//! ランデブの終了を通知する.
ercd = wi_ReplayRendPort( rdvno, msg, cmsgsz );
wi_CommonUnlock();
return ercd;
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブの終了.
*
* @param [in] rdvno ランデブ番号.
* @param [in] msg 返答メッセージのポインタ.
* @param [in] cmsgsz 返答メッセージのサイズ.
*
* @retval エラーコード.
*/
ER rpl_rdv( RDVNO rdvno, VP msg, UINT cmsgsz )
{
ER ercd;
wi_CommonLock();
//! ランデブの終了を通知する.
ercd = wi_ReplayRendPort( rdvno, msg, cmsgsz );
wi_CommonUnlock();
return ercd;
}
ランデブの終了関数
ランデブの終了関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief ランデブの終了.
*
* @param [in] rdvno ランデブ番号.
* @param [in] msg 返答メッセージのポインタ.
* @param [in] size 返答メッセージのサイズ.
*
* @retval エラーコード.
*/
ER wi_ReplayRendPort( INT no, VP msg, INT size )
{
ER ercd;
WIRDVOBJ *rdv;
WITSKOBJ *tsk;
//! ランデブ番号のオブジェクトを取得する.
rdv = (WIRDVOBJ *)wi_FindObject( no, TMAX_MAXRDV, RdvList, &ercd );
if( !rdv ){
return E_OBJ;
}
//! 引数が不正な場合はエラーにする.
if( rdv->MaxRepMsg < size ){
return E_PAR;
}
//! ランデブ終了待ちをしているタスクのコンテキストを取得する.
tsk = wi_GetTaskObject( rdv->TaskId );
if( !tsk ){
ercd = E_OBJ;
}else{
//! 返答メッセージをランデブ終了待ちをしているタスクのメッセージ領域にコピーする.
ercd = E_OK;
if( tsk->Param[1] && msg ){
if( (INT)tsk->Param[2] < size ){
tsk->Param[2] = 0;
ercd = E_PAR;
}else{
memcpy( tsk->Param[1], msg, size );
tsk->Param[2] = (VP)size;
}
}else{
tsk->Param[2] = 0;
}
//! ランデブ終了待ちをしているタスクを起床する.
wi_TaskWakeup( rdv->TaskId, TTW_RDV, NULL );
}
//! ランデブ・オブジェクトを削除する.
DeleteRdv( no );
return ercd;
}
ランデブの終了関数は以下のような処理を行います。
- 該当するランデブ番号のランデブ・オブジェクトをランデブ・リストから取り出します。
- 返答メッセージのサイズが不正な場合はエラー終了します。
- ランデブ終了待ちをしているタスクのコンテキストを取り出します。
- 返答メッセージをランデブ終了待ちをしているタスクのメッセージ領域にコピーします。
- ランデブ終了待ちをしているタスクを起床します。
- ランデブ・オブジェクトを削除します。
ランデブ・オブジェクトの削除は以下のようになります。
/****************************************************************************/
/*!
* @brief ランデブの削除.
*
* @param [in] no ランデブ番号.
*
* @retval なし.
*/
static void DeleteRdv( INT no )
{
ER ercd;
WIRDVOBJ *p;
//! ランデブポートIDのオブジェクトを取得する.
p = (WIRDVOBJ *)wi_FindObject( no, TMAX_MAXRDV, RdvList, &ercd );
if( p ){
//! リストから該当するランデブポートを取り除く.
wi_DelObject( (WIHDR *)p, &RdvList );
//! ランデブ・オブジェクト構造体を解放する.
SAFE_RELEASE( p );
}
}