Windows版 iTRONサービスコールの作成 (割り込み管理機能)
(その1)

概要

組み込みソフトウェアで利用されているOS「iTRON」のサービスコールをWindows上で動作させるためのライブラリです。

『割り込み管理機能』の実装を説明します。

割り込みハンドラの登録と割り込みの禁止/許可を実装します。

Ver4.0で定義されている割り込みサービス・ルーチンの実装は行いません。

割り込みハンドラはライブラリの外部から呼び出せる仕組みを作りましたので、擬似的な割り込み処理の確認が行えます。

サービスコール

 

・Ver3.0の割り込み管理機能で提供されるサービスコールは以下のとおりです。

サービスコール名説明
def_int

割り込みハンドラを登録します。

dis_int

割り込みを禁止します。

ena_int

割り込みを許可します。

ret_int

割り込みハンドラから復帰します。

ret_wup

割り込みハンドラから復帰して、指定したタスクを起床します。

loc_cpu

CPUをロック状態に移行します。

unl_cpu

CPUのロック状態を解除します。

 

・Ver4.0の割り込み管理機能で提供されるサービスコールは以下のとおりです。

サービスコール名説明
def_inh

割り込みハンドラを登録します。

cre_isr / acre_isr

割り込みサービス・ルーチンを生成します。

del_isr

割り込みサービス・ルーチンを削除します。

ref_isr

割り込みサービス・ルーチンの状態を参照します。

dis_int

割り込みを禁止します。

ena_int

割り込みを許可します。

loc_cpu

CPUをロック状態に移行します。

unl_cpu

CPUのロック状態を解除します。

割り込みハンドラの呼び出し

ライブラリの外部から割り込みハンドラを呼び出す為に以下の関数を用意しました。



    void request_interrupt( UINT num )
	

引数説明
num

割り込みハンドラ番号。

処理としては、割り込みハンドラを呼び出すスレッドに対して、呼び出す割り込みハンドラの番号をメッセージで通知するだけですので、すぐに制御を戻します。

 

割り込みハンドラの呼び出し用にスレッドを最上位の優先度(THREAD_PRIORITY_HIGHEST)で立ち上げます。

別スレッドからの割り込みハンドラ呼び出し要求を受けると、該当する割り込みハンドラが登録されていれば呼び出します。

dis_int()およびloc_cpu()にて該当する割り込みが禁止されている場合は割り込み要求の保留され、ena_int()またはunl_cpu()にて割り込みが許可されたときに割り込みハンドラを呼び出します。


/****************************************************************************/
/*!
 *  @brief  割り込みタスク.
 *
 *  @param  [in]    arg     タスクリソース構造体のポインタ.
 *
 *  @retval 常に0を返す.
 */
static unsigned __stdcall IntrTask( void* arg )
{
    MSG msg;

    //! スレッド識別子を取得する.
    IntrTid = GetCurrentThreadId();

    //! メッセージループ.
    while( GetMessage( &msg, NULL, 0, 0 ) ){

        //! システムの終了の場合はメッセージループを抜ける.
        if( msg.message == WM_SYSTEM_EXIT ){
            break;
        }
        switch( msg.message ){
        case WM_INTRRUPT_REQ:
            CallIntrruptHandler( (INT)msg.wParam );
            break;
        }
    }
    _endthreadex( 0 );
    return 0;
}

/****************************************************************************/
/*!
 *  @brief  割り込みハンドラを呼び出す.
 *
 *  @param  [in]    no      割り込みハンドラ番号.
 *
 *  @retval なし.
 */
static void     CallIntrruptHandler( INT no )
{
    wi_CommonLock();
    do {
        FP          intr_adr;
        ER          ercd;
        WIINTOBJ    *p;

        //! 割り込みハンドラ構造体を取り出す.
        p = (WIINTOBJ *)wi_FindObject( no, TMAX_MAXINT, ObjList, &ercd );
        if( !p ){
            break;
        }
        //! 割り込みエントリ・アドレスがない場合は呼び出さない.
        if( !p->IntrAdr ){
            break;
        }
        //! 割り込み禁止の場合は呼び出さない.
        if( !p->Enabled || wi_IsCPULock() ){
            p->IntrCnt++;
            break;
        }
        p->IntrCnt = 0;

        intr_adr = p->IntrAdr;

        wi_CommonUnlock();

        //! 割り込みハンドラを呼び出す.
        intr_adr();
        return;

    } while( FALSE );

    wi_CommonUnlock();
}
	

割り込みハンドラが登録されていない場合は処理を行いません。

また、割り込みハンドラが登録されていても、割り込みハンドラのエントリ・アドレスがない場合も処理を行いません。

割り込みが禁止されている場合は割り込み要求があったことをカウントして、処理を終了します。
(割り込み要求をカウントアップしていますが、割り込み禁止中に何回割り込み要求が発生しても、割り込み許可後には一度しか呼び出しません。)



商標に関する表示