请问Wince 5.0的下逻辑中断号的动态申请和固定分配到底是怎么回事

q91391   2010-6-6 15:45 楼主
这两天一直看WinCE 5.0下逻辑中断号的动态映射和动态分配的一些东西,产生一些问题,想向大家请叫?
    我现在手头上一块板子,EP9315,看了很多后,发现根据手头的资料分析,它正典型静态分配,interrupthandle()函数里(贴一断代码)
register ULONG   ulVic1Irq, ulVic2Irq;
    DWORD retval;
    LARGE_INTEGER tmpCurTicks;

    //
    // Read the interrupt status registers.
    //
    ulVic1Irq   = *VIC1_IRQSTATUS;
    ulVic2Irq   = *VIC2_IRQSTATUS;

    //
    // Set the default value to nop
    //   
    retval      = SYSINTR_NOP;

    //      
    // Fake CPUEnterIdle needs to know about interrupt firing.
    //
    if(ulVic1Irq & INT1_TIMER1)
    {
        //
        // Temporary hack for the PS2 keyboard driver.
        /*
        if((gdwInterruptMask2 & INT2_SPI) && (*SPI_SR & SPISR_RNE) && !fPS2Int)
        {
            fPS2Int         = 1;
            *VIC2_INTCLEAR  = INT2_SPI;
            retval          = SYSINTR_SPI;   
        }
        else*/
        {
            retval = TimerInterrupt();
            CPUClearSysTimerIRQ();
        }
        
        //
        //  Check if RTC Alarm arrived when TimerInterrupt returns NOP.
        //
        if( (gfRTCAlarm) && (retval == SYSINTR_NOP) )
        {
            // Tell the world that we were here....
            #if (1 == DEBUG_ALARM)
                OEMWriteDebugByte('e');
            #endif  // ( DEBUG_ALARM )
            tmpCurTicks.QuadPart = CurTicks.QuadPart ;
            if (gliRTCAlarmTicks.QuadPart <= tmpCurTicks.QuadPart)
            {
                #if (1 == DEBUG_ALARM)
                    // Tell the world that the interrupt was hit...
                    OEMWriteDebugByte('t');
                    OEMWriteDebugByte('\r');
                    OEMWriteDebugByte('\n');
                #endif  // ( DEBUG_ALARM )
                gfRTCAlarm = FALSE;
                retval = SYSINTR_RTC_ALARM;
            }
        }
    }

    else
    {              
       
        //
        // If we're timing interrupts, keep track of when this one came in
        //
        if (fIntrTime)
        {
            //
            // Subtract off dwReschedIncrment since interrupt hasn't been cleared
            //
            dwIsrTime1 = PerfCountSinceTick();
            wNumInterrupts++;
        }
        //
        // If we get any device interrupts, signal the resume flag.  The flag
        // will release the CPU from OEMPowerOff if the user had previously
        // chosen to suspend the platform.  In OEMPowerOff, only the interrupts
        // allowed to wake us up will be enabled so we needn't worry about
        // that here.
        //
        //gfResumeFlag = TRUE;

        //
        // This was not a timer interrupt, must be a device interrupt.
        // Change the priority of the interrupt by changing the order that
        // the interrupt is processed.
        //
        //
        // Ethernet interrupt.
        //
        if(ulVic2Irq & INT2_ETHERNET)
        {
            *VIC2_INTCLEAR = INT2_ETHERNET;
            retval = SYSINTR_ETHER;   
        }
        //
        // USB interrupt
        //
        else if(ulVic2Irq & INT2_USB)
        {
            *VIC2_INTCLEAR = INT2_USB;
            retval = SYSINTR_USB;   
        }
        //
        // Check the serial port interrupts.
        //
        else if(ulVic2Irq & INT2_UART1)
        {
            *VIC2_INTCLEAR = INT2_UART1;
            retval = SYSINTR_UART1;   
        }
        else if(ulVic2Irq & INT2_UART2)
        {
            *VIC2_INTCLEAR = INT2_UART2;
            retval = SYSINTR_UART2;   
        }
        else if(ulVic2Irq & INT2_UART3)
        {
            *VIC2_INTCLEAR = INT2_UART3;
            retval = SYSINTR_UART3;   
        }
        else if(ulVic1Irq & INT1_UNUSED1)
        {
            *VIC1_INTCLEAR = INT1_UNUSED1;
            retval         = SYSINTR_PIO_PLAYBACK;   
        }
        else if(ulVic1Irq & INT1_UNUSED2)
        {
            *VIC1_INTCLEAR = INT1_UNUSED2;
            retval         = SYSINTR_PIO_RECORD;   
        }

        //
        // Check to see if it is a keyboard interrupt
        //
        else if(ulVic1Irq & INT1_KEYPAD)
        {
            *VIC1_INTCLEAR = INT1_KEYPAD;
            retval = SYSINTR_KEYBOARD;   
        }

        //
        // Check to see if the SPI port has generated an interrupt.
        // This is used for the PS/2 keyboard driver.
        //
        else if(ulVic2Irq & INT2_SPI)
        {
            fPS2Int         = 1;
            *VIC2_INTCLEAR = INT2_SPI;
            retval = SYSINTR_SPI;   
        }
而在wince带的s3c2410采有是动态映射
ULONG OEMInterruptHandler(ULONG ra)
{
    UINT32 sysIntr = SYSINTR_NOP;
    UINT32 irq, irq2 = OAL_INTR_IRQ_UNDEFINED, mask;

    // Get pending interrupt(s)
    irq = INREG32(&g_pIntrRegs->INTOFFSET);

    // System timer interrupt?
    if (irq == IRQ_TIMER4) {

        // Clear the interrupt
        OUTREG32(&g_pIntrRegs->SRCPND, 1 << IRQ_TIMER4);
        OUTREG32(&g_pIntrRegs->INTPND, 1 << IRQ_TIMER4);

        // Rest is on timer interrupt handler
        sysIntr = OALTimerIntrHandler();
        
    }
    // Profiling timer interrupt?
    else if (irq == IRQ_TIMER2)
    {
        // Mask and Clear the interrupt.
        mask = 1 << irq;
        SETREG32(&g_pIntrRegs->INTMSK, mask);
        OUTREG32(&g_pIntrRegs->SRCPND, mask);
        OUTREG32(&g_pIntrRegs->INTPND, mask);

        // The rest is up to the profiling interrupt handler (if profiling
        // is enabled).
        //
        if (g_pProfilerISR)
        {
            sysIntr = g_pProfilerISR(ra);
        }
    }
    else
    {

#ifdef OAL_ILTIMING
        if (g_oalILT.active) {
            g_oalILT.isrTime1 = OALTimerCountsSinceSysTick();
            g_oalILT.savedPC = 0;
            g_oalILT.interrupts++;
        }        
#endif
   
        if (irq == IRQ_EINT4_7 || irq == IRQ_EINT8_23) {

            // Find external interrupt number
            mask = INREG32(&g_pPortRegs->EINTPEND);
            mask &= ~INREG32(&g_pPortRegs->EINTMASK);
            mask = (mask ^ (mask - 1)) >> 5;
            irq2 = IRQ_EINT4;
            while (mask != 0) {
                mask >>= 1;
                irq2++;
            }

            // Mask and clear interrupt
            mask = 1 << (irq2 - IRQ_EINT4 + 4);
            SETREG32(&g_pPortRegs->EINTMASK, mask);
            OUTREG32(&g_pPortRegs->EINTPEND, mask);

            // calculate mask for primary interrupt
            mask = 1 << irq;

            // update irq
            irq = irq2;

        }  else {

            // Mask the interrupt
            mask = 1 << irq;
            SETREG32(&g_pIntrRegs->INTMSK, mask);

        }

        // clear primary interrupt
        OUTREG32(&g_pIntrRegs->SRCPND, mask);
        OUTREG32(&g_pIntrRegs->INTPND, mask);

        // First find if IRQ is claimed by chain
        sysIntr = NKCallIntChain((UCHAR)irq);
        if (sysIntr == SYSINTR_CHAIN || !NKIsSysIntrValid(sysIntr)) {
            // IRQ wasn't claimed, use static mapping
            sysIntr = OALIntrTranslateIrq(irq);
        }

        // unmask interrupts in case it's NOP or invalid
        if (SYSINTR_NOP == sysIntr) {
            if (OAL_INTR_IRQ_UNDEFINED == irq2) {
                // Unmask the primary interrupt
                CLRREG32(&g_pIntrRegs->INTMSK, mask);
            } else {
                // Unmask the external interrupt
                mask = 1 << (irq2 - IRQ_EINT4 + 4);
                CLRREG32(&g_pPortRegs->EINTMASK, mask);
            }
        }

    }

    return sysIntr;
}

下面问题就产生了:
  1.动态映射相对于静态分配有什么好处?难道是这样做灵活吗?但是这样做多了一些函数调用,相对静态分配来讲,哪个物理中断对应那个逻辑中断一看就很明确。
2.动态映射的一个流程是怎么样的,在网上找到一些资料,但是发现都没怎么说清楚。那位能说清楚一点,谢谢!
3.在网上查到的资料有
VOID OALIntrMapInit()
{
    UINT32 i;
   
    OALMSG(OAL_FUNC&&OAL_INTR, (L"+OALIntrMapInit\r\n"));

    // Initialize interrupt maps
    for (i = 0; i < SYSINTR_MAXIMUM; i++) {
        g_oalSysIntr2Irq = OAL_INTR_IRQ_UNDEFINED;
    }
    for (i = 0; i < OAL_INTR_IRQ_MAXIMUM; i++) {
        g_oalIrq2SysIntr = SYSINTR_UNDEFINED;
    }

    OALMSG(OAL_FUNC&&OAL_INTR, (L"-OALIntrMapInit\r\n"));
}
这样初始化,逻辑中断号都是-1,没有什么意义啊,那每个每个特定的中断,又是在那里理更改的这个两个数组了。做了两个数组做什么,应该只要一个数组就行了,只要把IRQ映射到SYSINTR不就行了?

回复评论 (1)

无人回贴。问题太简单?
点赞  2010-6-6 20:09
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复