Windows版 iTRONサービスコールの作成 (時間管理機能)
(その3)
周期起動ハンドラを登録または生成するサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
def_cyc | 周期起動ハンドラを登録します。(Ver3.0のみ) |
cre_cyc | 周期ハンドラID番号を指定して周期起動ハンドラを生成します。(Ver4.0のみ) |
acre_cyc | 周期ハンドラID番号を自動割付けで周期起動ハンドラを生成します。(Ver4.0のみ) |
del_cyc | 周期ハンドラを削除します。(Ver4.0のみ) |
周期起動ハンドラを登録するには以下のサービスコールを使用します。
ER def_cyc( HNO cycno, const T_DCYC *pk_dcyc )
引数 | 説明 |
---|---|
cycno | 周期ハンドラ番号。 |
pk_dcyc | 周期ハンドラ定義情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外の周期ハンドラID番号。 |
E_PAR | パラメータエラー。 |
周期ハンドラ定義情報構造体(T_DCYC)は以下のとおりです。
メンバ名 | 説明 |
---|---|
exinf | 拡張情報。 |
cycatr |
周期ハンドラ属性。 周期ハンドラの起動方法を指定します。
|
cychdr | 周期ハンドラのアドレス。 |
cycact |
周期ハンドラの活性状態。 周期ハンドラの起動・停止を指定します。
|
cyctim | 周期起動時間間隔。 |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief 周期ハンドラ定義.
*
* @param [in] cycno 周期ハンドラ番号.
* @param [in] pk_dcyc 周期ハンドラ定義情報.
*
* @retval エラーコード.
*/
ER def_cyc( HNO cycno, const T_DCYC *pk_dcyc )
{
ER ercd;
WICYCOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_dcyc ){
return E_PAR;
}
//! 周期ハンドラ定義情報をコピーする.
memset( &obj, 0, sizeof(WICYCOBJ) );
obj.Attribute = pk_dcyc->cycatr;
obj.CycAdr = pk_dcyc->cychdr;
obj.Active = (pk_dcyc->cycact & TCY_ON) ? TRUE : FALSE;
obj.ExtInfo = pk_dcyc->exinf;
obj.CycleTime = ((DWORDLONG)(pk_dcyc->cyctim.utime) << 32) + (DWORDLONG)(pk_dcyc->cyctim.ltime);
wi_CommonLock();
//! 周期ハンドラを登録する.
ercd = wi_DefineCycleHadler( cycno, &obj, TRUE );
wi_CommonUnlock();
return ercd;
}
周期起動ハンドラの定義情報をコピーして、登録済みIDの場合の上書きを許可して周期ハンドラの登録関数を呼び出します。
周期ハンドラID番号を指定して周期起動ハンドラを生成する (Ver4.0のみ)
周期ハンドラID番号を指定して周期起動ハンドラを生成するには以下のサービスコールを使用します。
ER cre_cyc( ID cycid, const T_CCYC *pk_ccyc )
引数 | 説明 |
---|---|
cycid | 周期ハンドラID番号。 |
pk_ccyc | 周期ハンドラ生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外の周期ハンドラID番号。 |
E_PAR | パラメータエラー。 |
E_OBJ | 指定した周期ハンドラID番号は登録済み。 |
周期ハンドラ生成情報構造体(T_CCYC)は以下のとおりです。
メンバ名 | 説明 |
---|---|
cycatr |
周期ハンドラ属性。 周期ハンドラの起動方法を指定します。
TA_STAを指定した場合、周期ハンドラ生成後、周期ハンドラを起動します。 TA_PHSを指定した場合、周期ハンドラの起動位相を有効にします。(本ライブラリでは指定できません。) |
exinf | 拡張情報。 |
cychdr | 周期ハンドラのアドレス。 |
cyctim | 周期起動時間間隔。 |
cycphs | 周期起動位相。(本ライブラリでは使用しません。) |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief 周期ハンドラの生成.
*
* @param [in] cycid 周期ハンドラID番号.
* @param [in] pk_ccyc 周期ハンドラ生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER cre_cyc( ID cycid, const T_CCYC *pk_ccyc )
{
ER ercd;
WICYCOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_ccyc ){
return E_PAR;
}
//! 周期ハンドラ定義情報をコピーする.
memset( &obj, 0, sizeof(WICYCOBJ) );
obj.Attribute = pk_ccyc->cycatr;
obj.CycAdr = pk_ccyc->cychdr;
obj.Active = (pk_ccyc->cycatr & TA_STA) ? TRUE : FALSE;
obj.ExtInfo = pk_ccyc->exinf;
obj.CycleTime = ((DWORDLONG)(pk_ccyc->cyctim.utime) << 32) + (DWORDLONG)(pk_ccyc->cyctim.ltime);
obj.CyclePhs = ((DWORDLONG)(pk_ccyc->cycphs.utime) << 32) + (DWORDLONG)(pk_ccyc->cycphs.ltime);
wi_CommonLock();
//! 周期ハンドラを登録する.
ercd = wi_DefineCycleHadler( cycid, &obj, FALSE );
wi_CommonUnlock();
return ercd;
}
周期起動ハンドラの生成情報をコピーして、登録済みIDの場合の上書きを禁止して周期ハンドラの登録関数を呼び出します。
周期ハンドラID番号を自動割付けで周期起動ハンドラを生成する (Ver4.0のみ)
周期ハンドラID番号を自動割付けで周期起動ハンドラを生成するには以下のサービスコールを使用します。
ER acre_cyc( const T_CCYC *pk_ccyc )
引数 | 説明 |
---|---|
pk_ccyc | 周期ハンドラ生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_PAR | パラメータエラー。 |
E_NOID | ID番号不足。 |
上記以外の正数 | 生成した周期ハンドラのID番号。(正常終了) |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief 周期ハンドラの生成 (ID番号自動割り付け).
*
* @param [in] pk_ccyc 周期ハンドラ生成情報構造体のポインタ.
*
* @retval 生成した周期ハンドラのハンドラIDまたはエラーコード.
*/
ER acre_cyc( const T_CCYC *pk_ccyc )
{
ER_ID ercd;
ID cycid;
WICYCOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_ccyc ){
return E_PAR;
}
//! 周期ハンドラ定義情報をコピーする.
memset( &obj, 0, sizeof(WICYCOBJ) );
obj.Attribute = pk_ccyc->cycatr;
obj.CycAdr = pk_ccyc->cychdr;
obj.Active = (pk_ccyc->cycatr & TA_STA) ? TRUE : FALSE;
obj.ExtInfo = pk_ccyc->exinf;
obj.CycleTime = ((DWORDLONG)(pk_ccyc->cyctim.utime) << 32) + (DWORDLONG)(pk_ccyc->cyctim.ltime);
obj.CyclePhs = ((DWORDLONG)(pk_ccyc->cycphs.utime) << 32) + (DWORDLONG)(pk_ccyc->cycphs.ltime);
wi_CommonLock();
for( cycid = 1; cycid < TMAX_MAXCYC; cycid++ ){
//! 周期ハンドラを登録する.
ercd = wi_DefineCycleHadler( cycid, &obj, FALSE );
if( ercd == E_OK ){
ercd = cycid;
break;
}
}
if( ercd == E_OBJ ){
ercd = E_NOID;
}
wi_CommonUnlock();
return ercd;
}
周期ハンドラID番号を自動割付けで周期起動ハンドラを生成する関数は以下のような処理を行います。
- cre_cyc()と同様に、サービスコールのエントリ関数内で引数の構造体のメンバをコピーし、登録済みIDの場合の上書きを禁止して周期起動ハンドラ登録関数を呼び出します。
- 生成する周期起動ハンドラのID番号を1~TMAX_MAXCYCに+1づつカウントアップして、空いているID番号を探して周期起動ハンドラを生成します。
- 周期起動ハンドラが生成できた場合、戻り値を生成した周期起動ハンドラのID番号にして処理を終了します。
- 1~TMAX_MAXCYCの全てのID番号が使用中の場合、エラーコードが「E_OBJ(周期起動ハンドラ登録済み)」となるので、これを「E_NOID(ID番号不足)」に置き換えてエラー終了します。
周期起動ハンドラ登録関数
周期起動ハンドラ登録関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief 周期ハンドラ定義.
*
* @param [in] no 周期ハンドラ番号.
* @param [in] obj 周期ハンドラ・オブジェクト構造体のポインタ.
* @param [in] ovr TRUE = 登録済みIDに上書き.
*
* @retval エラーコード.
*/
ER wi_DefineCycleHadler( INT no, const WICYCOBJ *obj, BOOL ovr )
{
ER ercd;
WICYCOBJ *p;
p = (WICYCOBJ *)wi_GetObject( no, ObjList );
if( p ){
//! 登録済みハンドラに上書き禁止の場合はエラー終了にする.
if( !ovr ){
return E_OBJ;
}
//! 既に登録しているハンドラ番号の場合は登録を上書きする.
p->Hdr.Id = no;
p->Attribute = obj->Attribute;
p->CycAdr = obj->CycAdr;
p->Active = obj->Active;
p->ExtInfo = obj->ExtInfo;
p->CycleTime = obj->CycleTime;
p->StartTime = wi_GetSystemTime();
return E_OK;
}
//! 周期ハンドラ・オブジェクトを作成する.
p = (WICYCOBJ *)wi_CreateObject( no, TMAX_MAXCYC, sizeof(WICYCOBJ), obj, ObjList, &ercd );
if( !p ){
return ercd;
}
//! リストに周期ハンドラを追加する.
wi_AddObject( (WIHDR *)p, &ObjList );
return E_OK;
}
周期起動ハンドラ登録関数は以下のような処理を行います。
- 既に生成されている周期ハンドラ番号の場合、上書きが許可されていれば、既存の周期ハンドラ・オブジェクト構造体に、新たに登録する周期ハンドラ・オブジェクト構造体を上書きします。上書きが許可されていない場合はエラーで終了します。
- 生成されていない周期ハンドラ番号の場合、新しい周期ハンドラ・オブジェクトを生成します。
- 周期ハンドラ・リストに生成した周期ハンドラ・オブジェクトをリンクして処理を終了します。
周期ハンドラを削除するには以下のサービスコールを使用します。
ER del_cyc( ID cycid )
引数 | 説明 |
---|---|
cycid | 周期ハンドラID番号。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外の周期ハンドラID番号。 |
E_NOEXS | 指定した周期ハンドラID番号は登録されていない。 |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief 周期ハンドラの削除.
*
* @param [in] cycid 周期ハンドラID番号.
*
* @retval エラーコード.
*/
ER del_cyc( ID cycid )
{
ER ercd;
wi_CommonLock();
//! 周期ハンドラを削除する.
ercd = wi_DeleteCycleHadler( cycid );
wi_CommonUnlock();
return ercd;
}
削除する周期ハンドラのID番号を引数として周期ハンドラ削除関数を呼び出します。
周期ハンドラ削除関数
周期ハンドラ削除関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief 周期ハンドラの削除.
*
* @param [in] no 周期ハンドラ番号.
*
* @retval エラーコード.
*/
ER wi_DeleteCycleHadler( INT no )
{
ER ercd;
WICYCOBJ *p;
//! 周期ハンドラ番号のオブジェクトを取得する.
p = (WICYCOBJ *)wi_FindObject( no, TMAX_MAXCYC, ObjList, &ercd );
if( !p ){
return ercd;
}
//! リストから該当する周期ハンドラを取り除く.
wi_DelObject( (WIHDR *)p, &ObjList );
//! 周期ハンドラ・オブジェクト構造体を解放する.
SAFE_RELEASE( p );
return E_OK;
}
周期ハンドラ削除関数は以下のような処理を行います。
- 引数で指定された周期ハンドラ番号に該当する周期ハンドラ・オブジェクトを取り出します。
- 周期ハンドラ・オブジェクトのリストから削除するオブジェクトを外します。
- 周期ハンドラ・オブジェクトのために確保したメモリを解放して処理を終了します。