Windows版iTRONサービスコールの作成 (タスク管理)
(その2)

タスクを生成する

タスクを生成するサービスコールは以下のとおりです。


サービスコール名説明
cre_tsk

タスクID番号を指定してタスクを生成します。

acre_tsk

タスクID番号を自動割付けでタスクを生成します。

※ acre_tsk()はVer4.0のみサポートされます。

タスクID番号を指定してタスクを生成する

タスク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

タスクの属性。

タスクの起動方法を指定します。

  • TA_ASMの場合、アセンブリ言語用インターフェースで起動します。
  • TA_HLNGの場合、高級言語用インターフェースで起動します。
taskタスクのスタート・アドレス。
itskpri初期のタスク優先度。
stkszスタック・サイズ。(本ライブラリでは参照しません。)

Ver4.0のタスク生成情報構造体(T_CTSK)は以下のとおりです。

メンバ名説明
tskatr

タスクの属性。

タスクの起動方法を指定します。

  • TA_ASMの場合、アセンブリ言語用インターフェースで起動します。
  • TA_HLNGの場合、高級言語用インターフェースで起動します。

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 の場合はエラーにします。
  • 新しいタスク・オブジェクトを生成します。
  • 生成したタスクのステータスは「休止中」にします。
  • 各オブジェクトでの待ち行列で使用するイベント・ハンドルを作成します。
  • タスク・リストに生成したタスク・オブジェクトをリンクして処理を終了します。


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