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 );
    }
}
	



Windowsは米国Microsoft Corporationの登録商標です。