Windows版 iTRONサービスコールの作成 (イベントフラグ)
(その4)
イベントフラグのセットとクリアを行うサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
set_flg | イベントフラグをセットします。 |
iset_flg | イベントフラグをセットします。(非タスクコンテキストからの呼出し) |
clr_flg | イベントフラグをクリアします。 |
※ iset_flg()はVer4.0のみサポートされます。
イベントフラグにフラグパターンをセットしてイベント待ちをしているタスクを起床させます。
イベントフラグをセットするには以下のサービスコールを使用します。
※ Ver3.0とVer4.0ではフラグパターンの引数のデータ型が違いますので注意してください。
・Ver3.0の場合
ER set_flg( ID flgid, UINT setptn )
・Ver4.0の場合
ER set_flg( ID flgid, FLGPTN setptn )
引数 | 説明 |
---|---|
flgid | イベントフラグID番号。 |
setptn | セットするフラグパターン。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のイベントフラグID番号。 |
E_NOEXS | 指定したイベントフラグID番号は登録されていない。 |
E_PAR | 引数 setptn が不正な値。 |
Ver4.0では割り込みハンドラや周期起動ハンドラ等の非タスク処理内からの呼び出しは、set_flg()ではなく、iset_flg()を使用します。
ER iset_flg( ID flgid, FLGPTN setptn )
引数および戻り値は set_flg() と同じです。
・Ver3.0での set_flg() サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief イベントフラグのセット.
*
* @param [in] flgid イベントフラグID番号.
* @param [in] setptn セットするビットパターン.
*
* @retval エラーコード.
*/
ER set_flg( ID flgid, UINT setptn )
{
ER ercd;
wi_CommonLock();
//! イベントフラグをセットする.
ercd = wi_SetEvFlag( flgid, setptn );
wi_CommonUnlock();
return ercd;
}
・Ver4.0での set_flg() サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief イベントフラグのセット.
*
* @param [in] flgid イベントフラグID番号.
* @param [in] setptn セットするビットパターン.
*
* @retval エラーコード.
*/
ER set_flg( ID flgid, FLGPTN setptn )
{
ER ercd;
wi_CommonLock();
//! イベントフラグをセットする.
ercd = wi_SetEvFlag( flgid, (UINT)setptn );
wi_CommonUnlock();
return ercd;
}
フラグをセットするイベントフラグのID番号を引数としてイベントフラグ・セット関数を呼び出します。
・iset_flg() サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief イベントフラグのセット (非タスクコンテキストからの呼出し用).
*
* @param [in] flgid イベントフラグID番号.
* @param [in] setptn セットするビットパターン.
*
* @retval エラーコード.
*/
ER iset_flg( ID flgid, FLGPTN setptn )
{
//! イベントフラグをセットする.
return set_flg( flgid, setptn );
}
set_flg()を改めて呼び出すだけですので、set_flg()と同じ動作になります。
イベントフラグ・セット関数
イベントフラグにビットパターンをセットする関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief イベントフラグのセット.
*
* @param [in] id イベントフラグID番号.
* @param [in] setptn セットするビットパターン.
*
* @retval エラーコード.
*/
ER wi_SetEvFlag( INT id, UINT setptn )
{
ER ercd;
WIFLGOBJ *p;
WITSKOBJ *tsk,*next_link;
UINT tsk_flg,event_mode;
BOOL event_on;
//! イベントフラグIDのオブジェクトを取得する.
p = (WIFLGOBJ *)wi_FindObject( id, TMAX_MAXFLG, ObjList, &ercd );
if( !p ){
return ercd;
}
//! 引数が不正な場合はエラーにする.
if( setptn == 0 ){
return E_PAR;
}
//! 指定されたフラグをセットする.
p->FlgVal |= setptn;
tsk = (WITSKOBJ *)(p->WaitQue);
while( tsk ){
event_on = FALSE;
tsk_flg = (UINT)tsk->Param[0];
event_mode = (UINT)tsk->Param[1];
if( event_mode & TWF_ORW ){
//! OR待ちの場合、いずれかのビットが一致すればイベントを発行する.
if( (tsk_flg & p->FlgVal) != 0 ){
event_on = TRUE;
}
}else{
//! AND待ちの場合、全てのビットが一致すればイベントを発行する.
if( (tsk_flg & p->FlgVal) == tsk_flg ){
event_on = TRUE;
}
}
//! 次のイベント待ちタスクを取り出す.
next_link = tsk->QueLink;
if( event_on ){
//! イベント発生時のフラグパターンをタスク・オブジェクトに保存する.
tsk->Param[2] = (VP)(p->FlgVal);
//! フラグのクリア設定がされている場合はフラグをクリアする.
if( (event_mode & TWF_CLR) != 0 || (p->Attribute & TA_CLR) != 0 ){
p->FlgVal = 0;
}
//! イベント待ちをしているタスクを起床させる.
wi_TaskWakeup( tsk->Hdr.Id, TTW_FLG, &(p->WaitQue) );
}
tsk = next_link;
}
return E_OK;
}
イベントフラグにビットパターンをセットする関数は以下のような処理を行います。
- 引数で指定されたイベントフラグID番号に該当するイベントフラグ・オブジェクトを取り出します。
- イベントフラグにセットするフラグパターン(setptn)が0の場合はエラー終了にします。
- 現在のイベントフラグのビットパターンと指定されたビットパターンの論理和(OR)をとります。
- フラグのセット待ちをしているタスクの待ちフラグパターンと待ち条件によりタスクを起床させるかどうかを判定します。
- 待ち条件がTWF_ORWの場合、イベントフラグのビットパターンと待ち条件のビットパターンの論理積(AND)をとって、0以外になればタスクを起床します。
- 待ち条件がTWF_ANDWの場合、イベントフラグのビットパターンと待ち条件のビットパターンの論理積(AND)をとって、待ち条件のビットパターンと一致するときタスクを起床します。
- タスクの起床時に待ち行列から該当タスクは削除されてしまうので、起床するタスクにリンクしている次の待ち行列のタスクのポインタを退避しておきます。
- タスクを起床する前に、タスク起床時にイベントフラグのビットパターンをクリアする指示がある場合はイベントフラグのビットパターンを 0 にします。
- イベントフラグのセット待ちしている待ち行列の先頭のタスクを起床し、待ち行列から起床したタスクを外します。
イベントフラグの現在のフラグの値と引数で指定したフラグパターンの論理積(AND)をとり、現在のフラグ値にします。
フラグのクリアではイベント待ちをしているタスクの起床は行いません。
イベントフラグをクリアするには以下のサービスコールを使用します。
※ Ver3.0とVer4.0ではフラグパターンの引数のデータ型が違いますので注意してください。
・Ver3.0の場合
ER clr_flg( ID flgid, UINT clrptn )
・Ver4.0の場合
ER clr_flg( ID flgid, FLGPTN clrptn )
引数 | 説明 |
---|---|
flgid | イベントフラグID番号。 |
clrptn | 論理積をとるフラグパターン。(クリアするビットを「0」にします。) |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のイベントフラグID番号。 |
E_NOEXS | 指定したイベントフラグID番号は登録されていない。 |
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief イベントフラグのクリア.
*
* @param [in] flgid イベントフラグID番号.
* @param [in] clrptn クリアするビットパターン.
*
* @retval エラーコード.
*/
ER clr_flg( ID flgid, UINT clrptn )
{
ER ercd;
wi_CommonLock();
//! イベントフラグをクリアする.
ercd = wi_ClearEvFlag( flgid, clrptn );
wi_CommonUnlock();
return ercd;
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief イベントフラグのクリア.
*
* @param [in] flgid イベントフラグID番号.
* @param [in] clrptn クリアするビットパターン.
*
* @retval エラーコード.
*/
ER clr_flg( ID flgid, FLGPTN clrptn )
{
ER ercd;
wi_CommonLock();
//! イベントフラグをクリアする.
ercd = wi_ClearEvFlag( flgid, (UINT)clrptn );
wi_CommonUnlock();
return ercd;
}
フラグをクリアするイベントフラグのID番号を引数として共通のイベントフラグ・クリア関数を呼び出します。
イベントフラグ・クリア関数
イベントフラグのビットパターンをクリアする関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief イベントフラグのクリア.
*
* @param [in] id イベントフラグID番号.
* @param [in] clrptn クリアするビットパターン.
*
* @retval エラーコード.
*/
ER wi_ClearEvFlag( INT id, UINT clrptn )
{
ER ercd;
WIFLGOBJ *p;
//! イベントフラグIDのオブジェクトを取得する.
p = (WIFLGOBJ *)wi_FindObject( id, TMAX_MAXFLG, ObjList, &ercd );
if( !p ){
return ercd;
}
//! 指定されたフラグをクリアする.
p->FlgVal &= clrptn;
return E_OK;
}
イベントフラグのビットパターンをクリアする関数は以下のような処理を行います。
- 引数で指定されたイベントフラグID番号に該当するイベントフラグ・オブジェクトを取り出します。
- イベントフラグのビットパターンとクリアするビットパターンの論理積(AND)をとって、イベントフラグのビットマップパターンから指定されたビットをクリアします。
- イベントフラグのクリアではフラグセット待ちをしているタスクの起床は行いません。