embeddedなブログ

組み込みシステムに関することや趣味に関することをダラダラと書いていきます(^^)

デバイスドライバでの割り込み処理(Windows CE)

2012-04-25 19:41:29 | Windows Embedded CompactまたはCE

Windows CEのデバイスドライバで、割り込み処理をする方法について簡単に説明します。

下図がHW割り込み発生から、ISTが駆動されるまでの大まかな流れです。

ISR: 割り込みサービス ルーチン (Interrupt Service Routine) 割り込みソースを識別し、対応するIRQ番号をカーネルに返す。
SYSINTR: 割り込み識別子。割り込みソースを示すソフトウェア用の割り込み識別子。
IST: 割り込みサービス スレッド (Interrupt Service Thread) デバイスドライバで実行される割り込み処理用のスレッド。

(1)HW割り込みが発生すると、対応するISRが呼び出されます。ISRはIRQ番号をカーネルに渡します。 (2)カーネルはIRQ番号に関連づけられたSYSINTRを返します。 (3)そしてそのSYSINTRに関連づけられたEventがセットされます。 (4)WaitForSingleObjectにてEvent待ちをしていたISTが駆動され、割り込み処理が実行されます。

ドライバで実装するのは、この流れで必要な、 (2)HW割り込みID(識別子)とSYSINTRの関連づけ、 (3)SYSINTRとEventの関連づけ、そして (4)ISTの3つになります。

以下が、実際のコード例です。

#define IRQ_DEVICE0  35 // そのデバイスに割り振られているHWレベルでのIRQ番号
#define DEVICE_THREAD_PRIORITY  150 // ISTのスレッド優先度

typedef struct {
    HANDLE IntrThread;
    UINT32 SysIntr;
    HANDLE IntrEvent;
} DEVICE_STRUCT;

DEVICE_STRUCT *pDevice = NULL;
UINT32 irq = IRQ_DEVICE0;

// デバイス管理用構造体の生成
pDevice = (DEVICE_STRUCT *)LocalAlloc(LPTR, sizeof(DEVICE_STRUCT));
memset(pDevice, 0, sizeof(DEVICE_STRUCT));

// (2)デバイスのIRQ番号 IRQ_DEVICE0 に対応するSYSINTR の関連づけ
KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(UINT32), &pDevice->SysIntr, sizeof(UINT32), NULL);

// 割り込みスレッド駆動用イベントの生成
pDevice->IntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

// (3)SYSINTRとイベントの関連づけ(これで割り込み発生時に対応するイベントが駆動される)
InterruptInitialize(pDevice->SysIntr, pDevice->IntrEvent, NULL, 0);

// ISTの生成
DeviceIntrThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)DeviceInterruptThread, pDevice, 0, NULL);

// ISTの優先度設定
CeSetThreadPriority(pDevice->IntrThread, DEVICE_THREAD_PRIORITY);

// ISR本体
VOID DeviceInterruptThread(DEVICE_STRUCT *pDevice)
{
    while(TRUE) {
        // (4)Eventがセットされるのを待つ
        WaitForSingleObject(pDevice->IntrEvent, INFINITE);
        /* ここで割り込み処理を行う */
    }
}


最新の画像もっと見る