|
最近在折腾DM9000移植上CE5.0上,使用的是S3C2440的CE5.0官方BSP。打算使用静态中断处理的方法:
系统启动:ARMInit->OEMInit->OALIntrInit->OALIntrMapInit->(#ifdef OAL_BSP_CALLBACKS--BSPIntrInit->OALIntrStaticTranslate) ;
中断初始化:InterruptInitialize(驱动程序)->OEMInterruptEnable(微软实现)->OALIntrTranslateSysIntr(数据校验,把逻辑中断号变成IRQ号)->OALIntrEnableIrqs(OEM实现,通过IRQ号使能自定义的中断)->BSPIntrRequestIrqs->BSPIntrEnableIrq;
ISR实现:OEMInterruptHandler->(NKCallIntrChain)/OALIntrTranslateIrq 返回发生中断的IRQ对应的逻辑中断;
中断结束:InterruptDone->OEMInterruptDone->OALIntrDoneIrqs(BSPIntrDoneIrq);
------------------------------------------------
1.在具体中断初始化过程中,IST线程中调用InterruptInitialize(DWORD idInt,,,),进而调用OEMInterruptEnable(DWORD idInt,,):
- BOOL OEMInterruptEnable(DWORD sysIntr, LPVOID pvData, DWORD cbData)
- {
- BOOL rc = FALSE;
- const UINT32 *pIrqs;
- UINT32 count;
- OALMSG(OAL_INTR&&OAL_VERBOSE,
- (L"+OEMInterruptEnable(%d, 0x%x, %d)\r\n", sysIntr, pvData, cbData
- ));
- // SYSINTR_VMINI & SYSINTR_TIMING are special cases
- if (sysIntr == SYSINTR_VMINI || sysIntr == SYSINTR_TIMING) {
- rc = TRUE;
- goto cleanUp;
- }
- // Obtain the SYSINTR's underlying IRQ number
- [color=#FF0000] if (!OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) {[/color] // Indicate invalid SysIntr
- OALMSG(OAL_ERROR, (
- L"ERROR: OEMInterruptEnable: IRQs are undefined for SysIntr %d\r\n",
- sysIntr
- ));
- goto cleanUp;
- }
- // Enable the interrupt
- rc = [color=#FF0000]OALIntrEnableIrqs(count, pIrqs);[/color]
- cleanUp:
- OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OEMInterruptEnable(rc = 1)\r\n"));
- return rc;
- }
复制代码
再调用OALIntrTranslateSysIntr(DWORD idInt,,)函数:
- BOOL OALIntrTranslateSysIntr(UINT32 [color=#FF0000]sysIntr[/color], UINT32 *pCount, const UINT32 **ppIrqs) //第一个参数是输入,后两个是输出参数
- {
- BOOL rc;
- OALMSG(OAL_INTR&&OAL_VERBOSE, (L"+OALTranslateSysIntr(%d)\r\n", sysIntr));
-
- // Valid SYSINTR?
- if (sysIntr >= SYSINTR_MAXIMUM) {
- rc = FALSE;
- goto cleanUp;
- }
- *pCount = 1;
- *ppIrqs = &g_oalSysIntr2Irq[[color=#FF0000]sysIntr[/color]];//通过g_oalSysIntr2Irq数组转换得到IRQ号
- rc = TRUE;
- cleanUp:
- OALMSG(OAL_INTR&&OAL_VERBOSE, (L"-OALTranslateSysIntr(rc = %d)\r\n", rc));
- return rc;
- }
复制代码
2.OALIntrTranslateSysIntr()函数又调用OALIntrEnableIrqs()函数:
- BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *[color=#FF0000]pIrqs[/color])
- {
- BOOL rc = TRUE;
- UINT32 i, mask, irq;
- OALMSG(OAL_INTR&&OAL_FUNC, (
- L"+OALIntrEnableIrqs(%d, 0x%08x)\r\n", count, [color=#FF0000]pIrqs[/color]
- ));
- for (i = 0; i < count; i++) {
- #ifndef OAL_BSP_CALLBACKS
- [color=#FF0000]irq = pIrqs[i];[/color]
- #else
- // Give BSP chance to enable irq on subordinate interrupt controller
- [color=#FF0000]irq = BSPIntrEnableIrq(pIrqs[i]);//在未使用到多级中断控制器下,未作实际操作,直接返回pIrqs[i][/color]
- #endif
- if (irq == OAL_INTR_IRQ_UNDEFINED) continue;
- // Depending on IRQ number use internal or external mask register
- if (irq <= IRQ_ADC) {
- // Use interrupt mask register
- CLRREG32(&g_pIntrRegs->INTMSK, 1 << irq);
- } else if (irq <= IRQ_EINT7) {
- // Use external mask register
- CLRREG32(&g_pIntrRegs->INTMSK, 1 << IRQ_EINT4_7); //IRQ_EINT4_7~4
- CLRREG32(&g_pPortRegs->EINTMASK, 1 << (irq - IRQ_EINT4 + 4)); //IRQ_EINT4~32
- } else if (irq <= IRQ_EINT23) {
- // Use external mask register
- mask = 1 << (irq - IRQ_EINT4 + 4);
- OUTREG32(&g_pPortRegs->EINTPEND, mask);
- CLRREG32(&g_pPortRegs->EINTMASK, mask);
- mask = 1 << IRQ_EINT8_23;
- if ((INREG32(&g_pIntrRegs->INTPND) & mask) != 0) {
- OUTREG32(&g_pIntrRegs->INTPND, mask);
- }
- CLRREG32( &g_pIntrRegs->INTMSK, 1 << IRQ_EINT8_23);
- } else {
- rc = FALSE;
- }
- }
- OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrEnableIrqs(rc = %d)\r\n", rc));
- return rc;
- }
复制代码
这里就有疑问了,通过OALIntrTranslateSysIntr函数转换sysIntr成为IRQ号,但是这个IRQ号只拿来做了OAL调试输出信息的参数,后面的使能中断部分并没有使用到这个IRQ号啊?
而是使用了pIrqs这个数组,OALIntrRequestIrqs()和BSPIntrRequestIrqs()【功能是:获取设备的IRQ号(如通过IO Address获取该设备对应的IRQ)】,但是在中断流程中没有发现对这两个函数的调用啊?
何解啊?
我该怎么办?
请各位高手相助!
|
|