在Windows CE增加自訂中斷處理
基於S3C2410,Windows CE4.2,BSP是smdk2410。WinCE的中斷處理是三個映射關係:
ISQ --> Interrupt ID(邏輯中斷號) --> Event對象。
當中斷髮生時,ISR(插斷服務常式)返回該中斷號對應的邏輯中斷號,然後儘可能快地返回;隨後CE就set該邏輯中斷號對應的Event對象(如果有的話),以喚醒在該Event等待的IST(中斷服務線程),大部分工作都是由IST來完成。一般來說IST是存在驅動程式裡,單其實放在普通的應用程式裡也可以,尤其是對應只有一個應用程式使用的特殊硬體更方便。因為對應CE來說其實驅動程式也只是一個普通的DLL,也是運行在使用者空間。
為了簡單起見我們就直接修改BSP包的ISR部分,IST也直接在應用程式裡實現,步驟如下:
1、在BSP的oalintr.h裡定義自訂中斷的邏輯中斷值,如:
#define SYSINTR_MYINTR (SYSINTR_FIRMWARE + 10)
2、修改KERNEL/HAL/cfw.c中的以下三個函數,增加對自訂中斷的啟用禁用代碼:
OEMInterruptEnable(), OEMInterruptDisable(), OEMInterruptDone()
3、修改KERNEL/HAL/ARM/armint.c中的OEMInterruptHandler(),對irq返回邏輯中斷號,如:
else if (IntPendVal == INTSRC_EINT2) // EINT2
return(SYSINTR_MYINTR);
4、在PlatformBuilder中重建nk.bin,下載運行。
現在,核心已經支援我們的自訂中斷SYSINTR_MYINT了,我們在應用程式中就可以把這個SYSINTR_MYINT與一個Event對象關聯起來,然後在一個線程裡等待這個Event就ok了,這個線程就是IST。
5、在IST裡用InterruptInitialize()將自訂中斷和Event關聯起來,並WaitForSingleObject()。注意下面的代碼是在一個線程裡(即IST):
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL));
InterruptInitialize(SYSINTR_MYINTR, hEvent, NULL, 0)); //若沒有修改OEMInterruptEnable(),這個調用就會失敗
while ( TRUE )
{
WaitForSingleObject(hEvent, INFINITE);
// do some process...
}