Windows版 iTRONサービスコールの作成 (メールボックス)
(その4)

メールボックスへメッセージを送信する

メールボックスへメッセージを送信するサービスコールは以下のとおりです。


サービスコール名説明
snd_msg

メールボックスへメッセージを送信します。

※ Ver3.0、Ver4.0共に同じサービスコールの形式です。

メールボックスへメッセージを送信する

メールボックスへメッセージを送信するには以下のサービスコールを使用します。


    ER snd_msg( ID mbxid, T_MSG *pk_msg )
	

引数説明
mbxid

メールボックスID番号。

pk_msg

送信するメール・パケットのポインタ。

戻り値説明
E_OK

正常終了。

E_ID

範囲外のメールボックスID番号。

E_NOEXS

指定したメールボックスID番号は登録されていない。

E_PAR

パラメータエラー。


メッセージ・パケット構造体は以下のとおりです。

メンバ名説明
nextmsg

次のメッセージ・パケット構造体のポインタ。


・サービスコールのソースコードは以下のようになります。


/****************************************************************************/
/*!
 *  @brief  メールボックスへの送信.
 *
 *  @param  [in]    mbxid   メールボックスID番号.
 *  @param  [in]    pk_msg  メッセージ・パケットのポインタ.
 *
 *  @retval エラーコード.
 */
ER      snd_msg( ID mbxid, T_MSG *pk_msg )
{
    ER ercd;

    wi_CommonLock();

    //! メールボックスへメッセージを送信する.
    ercd = wi_SendMailBox( mbxid, pk_msg );

    wi_CommonUnlock();
    return ercd;
}
	

送信するメールボックスのID番号を引数としてメッセージ格納関数を呼び出します。

メッセージ格納関数

メールボックスへのメッセージ格納関数のソースコードは以下のとおりです。



/****************************************************************************/
/*!
 *  @brief  メールボックスへの送信.
 *
 *  @param  [in]    id      メールボックスID番号.
 *  @param  [in]    msg     メッセージ・パケットのポインタ.
 *
 *  @retval エラーコード.
 */
ER      wi_SendMailBox( INT id, T_MSG *msg )
{
    ER          ercd;
    WIMBXOBJ    *p;
    T_MSG       *msg_ptr;

    //! メールボックスIDのオブジェクトを取得する.
    p = (WIMBXOBJ *)wi_FindObject( id, TMAX_MAXMBX, ObjList, &ercd );
    if( !p ){
        return ercd;
    }
    //! 不正な引数の場合はエラーにする.
    if( !msg ){
        return E_PAR;
    }
    msg->nextmsg = NULL;
    if( (p->Attribute & TA_MPRI) != 0 ){
        //! 優先度順にメッセージを格納する場合.
        if( !(p->MsgQue) ){
            //! メッセージキューにメッセージがない場合はメッセージキューの先頭に格納する.
            p->MsgQue = msg;
        }else
        if( p->MsgQue->msgpri > msg->msgpri ){
            //! メッセージキューの先頭メッセージより優先度が高い場合もメッセージキューの先頭に格納する.
            msg->nextmsg = p->MsgQue;
            p->MsgQue    = msg;
        }else{
            msg_ptr = p->MsgQue;
            while( msg_ptr ){
                if( !(msg_ptr->nextmsg) ){
                    //! 次のメッセージがない場合はメッセージキューの最後にメッセージを格納する.
                    msg_ptr->nextmsg = msg;
                    break;
                }
                if( msg_ptr->nextmsg->msgpri > msg->msgpri ){
                    //! 次のメッセージより優先度が高い場合、次のメッセージの前にメッセージを格納する.
                    msg->nextmsg     = msg_ptr->nextmsg;
                    msg_ptr->nextmsg = msg->nextmsg;
                    break;
                }
                msg_ptr = msg_ptr->nextmsg;
            }
        }
    }else{
        //! メッセージ・パケット・リストにリンクされている最後のメッセージを探す.
        msg_ptr = p->MsgQue;
        while( msg_ptr ){
            if( !(msg_ptr->nextmsg) ){
                break;
            }
            msg_ptr = msg_ptr->nextmsg;
        }
        //! メッセージ・パケット・リストの最後に引数のメッセージ・パケットを追加する.
        if( msg_ptr ){
            msg_ptr->nextmsg = msg;
        }else{
            p->MsgQue = msg;
        }
    }
    //! メッセージ待ちをしているタスクがある場合はタスクを起床させる.
    if( p->WaitQue ){
        wi_TaskWakeup( p->WaitQue->Id, TTW_MBX, &(p->WaitQue) );
    }
    return E_OK;
}
	

メールボックスへのメッセージ格納関数は以下のような処理を行います。

  • 引数で指定されたメールボックスID番号に該当するメールボックス・オブジェクトを取り出します。
  • メッセージキューへのメッセージの格納方法が優先度順の場合、メッセージ・パケット・リストの先頭から順にメッセージの優先度を比較し、優先度の値が小さい方がメッセージキューの前になるようにメッセージを追加します。
  • メッセージキューへのメッセージの格納方法がFIFO順の場合、メッセージ・パケット・リストの最後にリンクされているメッセージを探し、メッセージ・パケット・リストの最後のメッセージに引数で指定されたメッセージパケットを追加します。
  • メッセージ受信待ちをしているタスクがある場合は、待ち行列の先頭のタスクを起床し、待ち行列から起床したタスクを外します。


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