Windows版iTRONサービスコールの作成 (タスク管理)
(その2)
タスクを生成するサービスコールは以下のとおりです。
サービスコール名 | 説明 |
---|---|
cre_tsk | タスクID番号を指定してタスクを生成します。 |
acre_tsk | タスクID番号を自動割付けでタスクを生成します。 |
※ acre_tsk()はVer4.0のみサポートされます。
タスクID番号を指定してタスクを生成するには以下のサービスコールを使用します。
※ Ver3.0とVer4.0では構造体のメンバが若干異なりますので注意してください。
ER cre_tsk( ID tskid, T_CTSK *pk_ctsk )
引数 | 説明 |
---|---|
tskid | タスクID番号。 |
pk_ctsk | タスク生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_OK | 正常終了。 |
E_ID | 範囲外のタスクID番号。 |
E_PAR | パラメータエラー。 |
E_OBJ | 指定したタスクID番号は登録済み。 |
Ver3.0のタスク生成情報構造体(T_CTSK)は以下のとおりです。
メンバ名 | 説明 |
---|---|
exinf | 拡張情報。 |
tskatr |
タスクの属性。 タスクの起動方法を指定します。
|
task | タスクのスタート・アドレス。 |
itskpri | 初期のタスク優先度。 |
stksz | スタック・サイズ。(本ライブラリでは参照しません。) |
Ver4.0のタスク生成情報構造体(T_CTSK)は以下のとおりです。
メンバ名 | 説明 |
---|---|
tskatr |
タスクの属性。 タスクの起動方法を指定します。
TA_ACTを指定すると、タスク生成後すぐにタスクが起動されます。 |
exinf | 拡張情報。 |
task | タスクのスタート・アドレス。 |
itskpri | 初期のタスク優先度。 |
stksz | スタック・サイズ。(本ライブラリでは参照しません。) |
stk | スタック領域の先頭アドレス。(本ライブラリでは参照しません。) |
Ver3.0とVer4.0で構造体のメンバが異なるので、それぞれのサービスコールのエントリ関数内で構造体のメンバを取り出してから、タスク生成処理を呼び出しています。
・Ver3.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief タスクの生成.
*
* @param [in] tskid タスクID番号.
* @param [in] pk_ctsk タスク生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER cre_tsk( ID tskid, const T_CTSK *pk_ctsk )
{
ER ercd;
WITSKOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_ctsk ){
return E_PAR;
}
//! タスク生成情報をコピーする.
memset( &obj, 0, sizeof(WITSKOBJ) );
obj.TaskAtr = pk_ctsk->tskatr;
obj.TaskAdr = pk_ctsk->task;
obj.TaskPri = pk_ctsk->itskpri;
obj.InitPri = pk_ctsk->itskpri;
obj.StackSize = pk_ctsk->stksz;
obj.ExtInfo = pk_ctsk->exinf;
wi_CommonLock();
//! タスクを生成する.
ercd = wi_CreateTask( tskid, &obj );
wi_CommonUnlock();
return ercd;
}
・Ver4.0のサービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief タスクの生成.
*
* @param [in] tskid タスクID番号.
* @param [in] pk_ctsk タスク生成情報構造体のポインタ.
*
* @retval エラーコード.
*/
ER cre_tsk( ID tskid, const T_CTSK *pk_ctsk )
{
ER ercd;
WITSKOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_ctsk ){
return E_PAR;
}
//! タスク生成情報をコピーする.
memset( &obj, 0, sizeof(WITSKOBJ) );
obj.TaskAtr = pk_ctsk->tskatr;
obj.TaskAdr = pk_ctsk->task;
obj.TaskPri = pk_ctsk->itskpri;
obj.InitPri = pk_ctsk->itskpri;
obj.StackSize = pk_ctsk->stksz;
obj.ExtInfo = pk_ctsk->exinf;
wi_CommonLock();
//! タスクを生成する.
ercd = wi_CreateTask( (DWORD)tskid, &obj );
//! TA_ACTが設定されている場合はタスクを起動する.
if( ercd == E_OK && (pk_ctsk->tskatr & TA_ACT) != 0 ){
wi_StartTask( (DWORD)tskid, 0, FALSE );
}
wi_CommonUnlock();
return ercd;
}
Ver4.0では、タスク属性に TA_ACT が指定されている場合、タスクの生成後すぐにタスクを起動します。
タスクID番号を自動割付けでタスクを生成する (Ver4.0のみ)
タスクID番号を自動割付けでタスクを生成するには以下のサービスコールを使用します。
ER_ID acre_tsk( const T_CTSK *pk_ctsk )
引数 | 説明 |
---|---|
pk_ctsk | タスク生成情報構造体のポインタ。 |
戻り値 | 説明 |
---|---|
E_PAR | パラメータエラー。 |
E_NOID | ID番号不足。 |
上記以外の正数 | 生成したタスクのID番号。(正常終了) |
・サービスコールのソースコードは以下のようになります。
/****************************************************************************/
/*!
* @brief タスクの生成 (ID番号自動割り付け).
*
* @param [in] pk_ctsk タスク生成情報構造体のポインタ.
*
* @retval 生成したタスクのタスクIDまたはエラーコード.
*/
ER_ID acre_tsk( const T_CTSK *pk_ctsk )
{
ER_ID ercd;
DWORD tskid;
WITSKOBJ obj;
//! 引数が不正な場合はエラーにする.
if( !pk_ctsk ){
return E_PAR;
}
//! タスク生成情報をコピーする.
memset( &obj, 0, sizeof(WITSKOBJ) );
obj.TaskAtr = pk_ctsk->tskatr;
obj.TaskAdr = pk_ctsk->task;
obj.TaskPri = pk_ctsk->itskpri;
obj.InitPri = pk_ctsk->itskpri;
obj.StackSize = pk_ctsk->stksz;
obj.ExtInfo = pk_ctsk->exinf;
wi_CommonLock();
for( tskid = 1; tskid < TMAX_MAXTSK; tskid++ ){
//! タスクを生成する.
ercd = wi_CreateTask( tskid, &obj );
if( ercd == E_OK ){
//! 戻り値を生成したタスクID番号にする.
ercd = (ER_ID)tskid;
//! TA_ACTが設定されている場合はタスクを起動する.
if( (pk_ctsk->tskatr & TA_ACT) != 0 ){
wi_StartTask( tskid, 0, FALSE );
}
break;
}
}
if( ercd == E_OBJ ){
ercd = E_NOID;
}
wi_CommonUnlock();
return ercd;
}
タスクID番号を自動割付けでタスクを生成する関数は以下のような処理を行います。
- cre_tsk()と同様に、サービスコールのエントリ関数内で引数の構造体のメンバをコピーし、タスク生成関数を呼び出します。
- 生成するタスクのID番号を1~TMAX_MAXTSKに+1づつカウントアップして、空いているID番号を探してタスクを生成します。
- タスクが生成できた場合、戻り値を生成したタスクのID番号にして処理を終了します。
- タスク属性に TA_ACT が指定されている場合、タスクの生成後すぐにタスクを起動します。
- 1~TMAX_MAXTSKの全てのID番号が使用中の場合、エラーコードが「E_OBJ(タスク登録済み)」となるので、これを「E_NOID(ID番号不足)」に置き換えてエラー終了します。
タスク生成関数
タスクを生成する関数のソースコードは以下のとおりです。
/****************************************************************************/
/*!
* @brief タスクを生成する.
*
* @param [in] id タスクID番号.
* @param [in] obj タスク・オブジェクト構造体のポインタ.
*
* @retval エラーコード.
*/
ER wi_CreateTask( INT id, const WITSKOBJ *obj )
{
ER ercd;
WITSKOBJ *p;
//! タスク・オブジェクトを作成する.
p = (WITSKOBJ *)wi_CreateObject( id, TMAX_MAXTSK, sizeof(WITSKOBJ), obj, ObjList, &ercd );
if( !p ){
return ercd;
}
//! 引数が不正な場合はエラーにする.
if( !obj->TaskAdr || obj->InitPri == 0 ){
return E_PAR;
}
//! タスクの状態を「休止中」にする.
p->TaskState = TTS_DMT;
//! イベント・ハンドルを作成する.
p->hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
if( !p->hEvent ){
SAFE_RELEASE( p );
return E_SYS;
}
//! リストにタスクを追加する.
wi_AddObject( (WIHDR *)p, &ObjList );
return E_OK;
}
タスクを生成する関数は以下のような処理を行います。
- タスクの起動アドレスが NULL か、初期優先度が 0 の場合はエラーにします。
- 新しいタスク・オブジェクトを生成します。
- 生成したタスクのステータスは「休止中」にします。
- 各オブジェクトでの待ち行列で使用するイベント・ハンドルを作成します。
- タスク・リストに生成したタスク・オブジェクトをリンクして処理を終了します。