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番号に該当するランデブポート・オブジェクトを取り出します。
  • 引数で指定されたランデブ番号に該当するランデブ・オブジェクトを取り出します。
  • ランデブ受付け待ちをしているタスクがある場合、ランデブ条件ビットパターンをチェックして、ランデブが成立するかどうかを調べます。
  • ランデブが成立しない場合、ランデブ終了待ちをしているタスクのイベント待ち状態を「ランデブ終了待ち」から「ランデブ成立待ち」にして、引数で指定されたランデブ・ポートの呼び出し待ち行列に追加します。
  • ランデブが成立した場合、以下の処理を行います。
    1. 『ランデブ・オブジェクト』を生成します。
    2. ランデブ受付けタスクに引数で指定されたメッセージをコピーします。
    3. ランデブ受付けタスクを起床します。
  • 引数で指定されたランデブ番号に該当するランデブ・オブジェクトを削除します。


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