WINCE 中断处理的迷惑

liuxin00738   2009-3-7 12:05 楼主
我用的是sangsun2440,号称是WINCE5.0 BSP的开发板.现因处理一按键(对应EINT19)中断.陷入迷惑.

BSP里面的OEMinit函数如下:
void OEMInit()  
{
        volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;

        // Instead of calling OEMWriteDebugString directly, call through exported
        // function pointer.  This will allow these messages to be seen if debug
        // message output is redirected to Ethernet or the parallel port.  Otherwise,
        // lpWriteDebugStringFunc == OEMWriteDebugString.
        lpWriteDebugStringFunc(TEXT("\nWindows CE Firmware Init\r\n"));



//if(!B)
        //lpWriteDebugStringFunc(TEXT("HookInterrupt Failed...\r\n"));




#ifdef MODULE_CERTIFY
        //
        // Set the module signature verification hooks
        //
        pOEMLoadInit   = OEMLoadInit;
        pOEMLoadModule = OEMLoadModule;
        //
        // Init the signature verification public key
        //
        InitPubKey(g_bSignPublicKeyBlob,sizeof(g_bSignPublicKeyBlob));
#endif

    //
    // Set up translation constant for GetIdleTime() (1 ms units).
    // Note: Since curridlehigh, curridlelow is counting in ms, and GetIdleTime()
    // reports in ms, the conversion ratio is one.  If curridlehigh, curridlelow
    // were using other units (like ticks), then the conversion would be calculated
    // from the clock frequency.
    //
    idleconv = 1;

        // Initialize interrupts.
        //
    lpWriteDebugStringFunc(TEXT("INFO: Initializing system interrupts...\r\n"));
        OEMInitInterrupts();  //出此函数源码贴在下面

        // Initialize the system clock(s).
        //
    lpWriteDebugStringFunc(TEXT("INFO: Initializing system clock(s)...\r\n"));
    InitClock();

    // Initialize driver globals area.
        //
    lpWriteDebugStringFunc(TEXT("INFO: Initializing driver globals area...\r\n"));
    memset((PVOID)DRIVER_GLOBALS_ZEROINIT_START, 0, DRIVER_GLOBALS_ZEROINIT_SIZE);
   
    // Initialize S2440X01 LCD controller
        InitDisplay();
#ifdef YL_2440_SUPPORT
        HzhInitPIO();
#endif
       
    // Initialize debug Ethernet (KITL) connection.
    //
        // InitDebugEther();       

        // Initialize GPIO        /// ;;; SHL
        s2440IOP->rPAD9 = (1<<12) | (0<<11);        // what is rPAD9? hzh
        //s2440IOP->rGPJCON = 0x016aaaa;
        //s2440IOP->rGPJUP  = ~((0<<12) | (1<<11));

        s2440IOP->rGPHCON = (s2440IOP->rGPHCON & ~(0xf<<18)) | (1<<20) | (1<<18);        // CLKOUT1, CLKOUT0

        s2440IOP->rDSC0 = 0x3ff;
        s2440IOP->rDSC1 = 0x3fffffff;

        // camera
        //Camera_Initialize();
        //s2440IOP->rGPJCON = 0x2aaaaaa;
//        s2440IOP->rGPJUP  = 0x1fff;

        InitSDMMC();

        // Initialize the ROM chain (multi-region).
        //
//        InitRomChain();
        lpWriteDebugStringFunc(TEXT("OEMInit Done...\r\n"));
        lpWriteDebugStringFunc(TEXT("fhg******************************\r\n"));
}



static void OEMInitInterrupts(void)        // for KITL 030828
{
        volatile INTreg *s2440INT = (INTreg *)INT_BASE;
        volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;

        // Configure EINT14 for DM9000 interrupt.
        s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 12)) | (0x2 << 12);        // GPG6 == EINT14.
        s2440IOP->rGPGUP   = (s2440IOP->rGPGUP   |  (0x1 << 6));                                                // Disable pull-up.
        s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 24)) | (0x1 << 24);                // Level-high triggered.

        // Configure EINT9 for CS8900 interrupt.
        s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x2)) | (0x2 << 0x2);                // GPG1 == EINT9.
        s2440IOP->rGPGUP   = (s2440IOP->rGPGUP   |  (0x1 << 0x1));                                                // Disable pull-up.
        s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x4)) | (0x1 << 0x4);                // Level-high triggered.
#ifndef YL_2440_SUPPORT
        // Configure EINT8 for PD6710 interrupt.
        //
        s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x0)) | (0x2 << 0x0);                // GPG0 == EINT8.
        s2440IOP->rGPGUP   = (s2440IOP->rGPGUP   |  (0x1 << 0x0));                                                // Disable pull-up.
        s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0xf << 0x0)) | (0x1 << 0x0);                // Level-high triggered.
#endif
        // Mask and clear all peripheral interrupts (these come through a second-level "GPIO" interrupt register).
        //
        s2440IOP->rEINTMASK = BIT_ALLMSK;        // Mask all EINT interrupts.
        s2440IOP->rEINTPEND = BIT_ALLMSK;        // Clear pending EINT interrupts.

        // Mask and clear all interrupts.
        //
        s2440INT->rINTMSK = BIT_ALLMSK;                        // Mask all interrupts (reset value).
        s2440INT->rINTMSK &= ~BIT_BAT_FLT;
        s2440INT->rSRCPND = BIT_ALLMSK;                        // Clear pending interrupts.
        s2440INT->rINTPND = s2440INT->rINTPND;                // S3C2440X developer notice (page 4) warns against writing a 1 to any
                                                        // 0 bit field in the INTPND register.  Instead we'll write the INTPND value itself.
}


我的问题是:从OEMinit函数看,此BSP并没有实现5.0所说的关于中断的几个函数(如: OALIntrInit(),OALIntrMapInit()等)
若归为4.2BSP(疑惑1:按理也该在OEMinit函数里调用HookInterrupt函数实现ISQ与ISR(OEMInterruptHandler)关联啊,可也没有),则若要自定义一中断方法可为下:

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返回逻辑中断号
5、在IST里用InterruptInitialize()将自定义中断和Event关联起来,并WaitForSingleObject()。



疑惑2:我按上面的方法编了一按键驱动,结果是驱动正常加载,可就是在WaitForSingleObject()中等不到与自定义的逻辑中断号SYSINTR_SW9相关联的事件发生(测试过按键是好的). 而也是按此方法实现的 BSP里自带的PWR按键处理却可以正常工作.

  
请各位高人不吝赐教!!!

回复评论 (10)

引用: 引用楼主 ystcreatcom 的帖子:
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返回逻辑中断号
5、在IST里用InterruptInitialize()将自定义中断和Event关联起来,并WaitForSingleObject()。


疑惑2:我按上面的方法编了一按键驱动,结果是驱动正常加载,可就是在WaitForSingleObject()中等不到与自定义的逻辑中断号SYSINTR_SW9相关联的事件发生(测试过按键是好的). 而也是按此方法实现的 BSP里自带的PWR按键处理却可以正常工作.



你的 是4.2BSP啊,5.0BSP不是这样的。

关于4.2BSP的中断,网上很多文章,算是比较好办的。

如果不能产生中断,那么用一些应用程序读出相关的寄存器看看,是否设置正确。

good luck!
点赞  2009-3-7 12:31
从代码看像优龙提供的4.2BSP。

5.0的看看我的博客。
4.2的网上很多介绍。
点赞  2009-3-7 12:34
5.0的中断处理可以用2种方法,4.2的那种也可以用,不过不推荐。
点赞  2009-3-7 21:33
   是4.2的BSP.现在问题是:我按大家说的添加自定义中断的方法怎么就不行呢?是哪里出问题了?

步骤如下:

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返回逻辑中断号
5、在IST里用InterruptInitialize()将自定义中断和Event关联起来,并WaitForSingleObject()。
点赞  2009-3-9 09:13
按照你的步骤已经没有错误了。有可能是你初始化有些问题(把IO配置成中断模式,中断以何种方式触发等)。或者是你在上面的几个OEM函数配置不正确。甚至这个中断被别的驱动占用了,这个一般在用别人的BSP的时候要尤其小心。

我不是叫你写个应用程序读寄存器的值,看看是否正确吗?

sunrain_hjb牛人写了不少wince开发工具的。

http://blog.eeworld.net/gooogleman/archive/2009/02/05/3864269.aspx

http://blog.eeworld.net/gooogleman/archive/2009/03/02/3948503.aspx
点赞  2009-3-9 09:42
按照你的步骤已经没有错误了。有可能是你初始化有些问题(把IO配置成中断模式,中断以何种方式触发等)。或者是你在上面的几个OEM函数配置不正确。甚至这个中断被别的驱动占用了,这个一般在用别人的BSP的时候要尤其小心。

我不是叫你写个应用程序读寄存器的值,看看是否正确吗?

sunrain_hjb牛人写了不少wince开发工具的。

http://blog.eeworld.net/gooogleman/archive/2009/02/05/3864269.aspx

http://blog.eeworld.net/gooogleman/archive/2009/03/02/3948503.aspx
点赞  2009-3-9 09:42
你看看你驱动中间是不是alloc了IO空间就直接free了
点赞  2009-3-9 09:49
BSP 结构不一样
点赞  2009-3-9 10:14
make
点赞  2009-6-10 17:58
我也遇到同样的问题
点赞  2010-5-28 20:26
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复