1 WinCE中第一次對中斷的處理是在OAL的OEMInit()中,該函數(shù)調用OALIntrInit()完成對中斷的初始化。
2 OALIntrInit()對中斷的初始化做了如下工作:
2.1 通過配置IPR0-IPR33設置中斷優(yōu)先級,優(yōu)先級定義在g_IntPriorities和g_IntPriorities2中,其中IRQ_OSMR0為最高優(yōu)先級, IRQ_KEYPAD為最低優(yōu)先級。
2.2 設置ICCR,在空閑模式時只對有效的,非屏蔽的中斷響應。
2.3 BSPIntrInit()。該函數(shù)對BSP中需要處理的中斷進行初始化工作,主要是設置ICMR寄存器使GPIO1(CPLD)和GPIO2為非屏蔽狀態(tài),然后通過OALIntrStaticTranslate建立IRQ和sysintr之間的關聯(lián)。
2.4 對于WinCE來說,中斷可以作如下分類:
1》 與BSP無關的Kernel使用的內部中斷, 比如IRQ_OSMR0(for
sched),IRQ_RTCALARM;
2》 與BSP有關的CPU內部中斷,比如IRQ_USBOHCI, IRQ_OSM
R1, IRQ_KEYPAD, IRQ_FFUART, IRQ_BTUART, IRQ_STUART, IRQ_DMAC, IRQ_USBFN;
3》 CPLD所管理的中斷,以GPIO1通知CPU中斷的產(chǎn)生,在收到G
PIO1產(chǎn)生的中斷后可以通過讀取地址0x0A00_0010判斷具體的中斷源,比如IRQ_GPIO1_MMCCD(MMC_IN_INT, MMC_OUT_INT), IRQ_GPIO1_USBCD(USB_IN_INT, USB_OUT_INT), IRQ_GPIO1_PCMCIA_S0_CSC(CF_IN_INT. CF_OUT_INT),還有在代碼中沒有處理的SIM卡中斷(SIM_IN_INT, SIM_OUT_INT)。
4》 GPIO2_120產(chǎn)生的中斷,通過寄存器ICIP的位10-GPIO_x通
知CPU中斷的產(chǎn)生,然后查詢寄存器GEDR_x可以判斷具體的中斷源,比如IRQ_GPIO12_MARATHO, IRQ_GPIO10_ETHERNET,IRQ_GPIO13_UCB1400;
5》 以Installable ISR形式產(chǎn)生的中斷,這類中斷通常是以DLL的形式安裝,在注冊表中定義其實際的IRQ中斷值,比如IRQ_MMC_DETECT,IRQ_MMC_CONTROL;
2.5 有幾種方式可以建立實際中斷IRQ到系統(tǒng)中斷sysintr之間的關聯(lián),對于build-in設備,可以在OEMInit中通過OALIntrStaticTranslate來建立靜態(tài)的關聯(lián);但是對于installable ISRs,可以在注冊表中定義實際的中斷IRQ,然后通過在KernelIOControl中使用IOCTL_HAL_REQUEST_SYSINTR來實時分配新的sysintr,這有助于驅動的移植。
3 在CPU接收到中斷后,對中斷的處理是在 OEMInterruptHandler()中,該函數(shù)的首先屏蔽該中斷,最后得到實際中斷IRQ所對應的sysintr的值。
3.1 首先它通過中斷寄存器ICHP得到實際的IRQ值;
3.2 對于GPIO產(chǎn)生的中斷,通過清空GFER和GRER寄存器來屏蔽相同的中斷;對于其余的CPU內部中斷,通過清空ICMR寄存器的相應位來屏蔽中斷;
3.3 對于Kernel使用的IRQ_OSMR0和IRQ_OSMR2,分別進行處理,得到sysintr;
3.4 對于通過GPIO0,GPIO1和GPIO2_120產(chǎn)生的中斷,將IRQ的值進行轉化,使之與OAL/intr.c和bulverder_intr.h中所定義的新的IRQ值相對應,此時的IRQ值就不是在ICIP中對定義的IRQ值了;
3.5 接著調用NKCallIntChain(irq)判斷該IRQ是否已經(jīng)被加入中斷列表,同時開始調用該中斷的ISR程序。
4 當中斷處理完成后,調用OALIntrDoneIrqs(),重新使能中斷。
(審核編輯: 智匯小新)