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順の場合、メッセージ・パケット・リストの最後にリンクされているメッセージを探し、メッセージ・パケット・リストの最後のメッセージに引数で指定されたメッセージパケットを追加します。
- メッセージ受信待ちをしているタスクがある場合は、待ち行列の先頭のタスクを起床し、待ち行列から起床したタスクを外します。