zoukankan      html  css  js  c++  java
  • CE 的中断

    CE 的中断

    (2008-10-26 20:59:04)
    标签:

    杂谈

    分类: CEstudynote

    中断

    WCE有两种私有的中断表,一种是物理中断——中断请求(IRQs),另一种是逻辑中断——SYSINTR值。WinCE必须将一个物理中断和一个逻辑中断关联起来。而且,这两者必须是唯一的,而且是delicated.

    物理中断号for example:

    #define IRQ_GPIO0_WIFI      IRQ_BULVERDE_MAX+9

    #define OAL_INTR_IRQ_MAXIMUM    64

    该值表示物理中断——IRQs的最大值,现在最大只支持到64

    逻辑中断号定义在:for example:

    #define SYSINTR_WIFI   SYSINTR_FIRMWARE+16  sysintr_firmware 也代表最大值。

     两个中断表,定义在platformc8090platformsrccommonintrasemap.c

    static UINT32  g_oalSysIntr2Irq[SYSINTR_MAXIMUM];

    static UINT32  g_oalIrq2SysIntr[OAL_INTR_IRQ_MAXIMUM];

     

    #define SYSINTR_DEVICES     8

    #define SYSINTR_MAX_DEVICES 64

    #define SYSINTR_MAXIMUM     (SYSINTR_DEVICES+SYSINTR_MAX_DEVICES)

     

    1. define IRQ and sysintr

    OEM Adaptation Layer——OAL初始化函数是OEMInit(),它是WinCEOAL层初始化函数,在基本初始化完成之后,由内核调用,定义在:

    platformc8090platformmainstoneiisrckerneloalinit.c

    在这里调用中断初始化函数:OALIntrInit(),该函数定义在:

    platformc8090platformcommonsrcarmintelpxa27xintrintr.c中,该函数首先调用函数OALIntrMapInit(),初始化前面提到的两个数组表g_oalSysIntr2IrqgoalIrq2SysIntr。该函数定义在platformc8090platformcommonsrccommonintrasemap.c,源码如下:

        for (i = 0; i < SYSINTR_MAXIMUM; i++) {

            g_oalSysIntr2Irq[i] = OAL_INTR_IRQ_UNDEFINED;

        }

        for (i = 0; i < OAL_INTR_IRQ_MAXIMUM; i++) {

            g_oalIrq2SysIntr[i] = SYSINTR_UNDEFINED;

    }

     

    2. map IRQ to sysintr

    然后调用函数BSPIntrInit()将物理中断和逻辑中断关联起来,该函数定义在:

    platformc8090platformmainstoneiisrckerneloalintr.c中。

    关联代码例子如下:

           OALIntrStaticTranslate(SYSINTR_PMIC, IRQ_GPIO0);   

           OALIntrStaticTranslate(SYSINTR_OHCI, IRQ_USBOHCI);

           OALIntrStaticTranslate(SYSINTR_TOUCH, IRQ_GPIOXX_WM9712);

           OALIntrStaticTranslate(SYSINTR_TOUCH_CHANGED, IRQ_OSMR1);

           OALIntrStaticTranslate(SYSINTR_KEYPAD, IRQ_KEYPAD);

    前面都是逻辑中断,后面是物理中断。OALIntrStaticTranslate函数定义在:

    platformc8090platformcommonsrccommonintrasemap.c,源码如下:

        if (irq < OAL_INTR_IRQ_MAXIMUM && sysIntr < SYSINTR_MAXIMUM) {

            g_oalSysIntr2Irq[sysIntr] = irq;

            g_oalIrq2SysIntr[irq] = sysIntr;

    }       

    3.  interrupt initialize

       set GPIO configuration

       set interrupt information including IRQ,system interrupt, IST function and so on.

    setup interrupt: Use ISR to process interrupt

                  1. create interrupt event to interruptevent:

               if(!(pMyIntrInfo->hIntrEvent = CreateEvent( NULL, FALSE, FALSE, NULL))) {         DEBUGMSG(1, (TEXT("CreateEvent() FAILED")));         goto errFuncRet;     }

                  2. convert the irq into sysinterrupt (kernelIoControl()accesses kernel to transfer OEMIoControl.   OEMIoControl use I/O to achieve some function.)

                  IOCTL_HAL_REQUEST_SYSINTR makes OAL return the relative sysintr according to irq.

               if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &pMyIntrInfo->irq, sizeof(DWORD),

                &pMyIntrInfo->dwSysIntr, sizeof(pMyIntrInfo->dwSysIntr), NULL))

                  3. create IST according to sysintr.

    pMyIntrInfo->hISTHandle = CreateThread((LPSECURITY_ATTRIBUTES)NULL,                                          0,                                           myIST,                                           pMyIntrInfo,                                           CREATE_SUSPENDED,                                           &threadID);

                  4. set the priority to the IST.

    CeSetThreadPriority(pMyIntrInfo->hISTHandle, DEFAULT_IST_PRIORITY);

                  5. mask the other interrupt with the same or lower level.(OEMIterruptDisable)

                   InterruptDisable(pMyIntrInfo->dwSysIntr);

                    interrupt service controller program (ISCP) transfers OEMinterruptDisable to close the relative interrupt pin.( mask controller)

                  6. use interruptinitialize to make kernel transfer OEMInterruptEnable to create mapping between ISR and IST.

    if (! InterruptInitialize(pMyIntrInfo->dwSysIntr, pMyIntrInfo->hIntrEvent, NULL, 0)) {   DEBUGMSG(1, (TEXT("%s - InterruptInitialize(%d,%08x) Failed "),

    generate IST process the interrupt.

                 1. get the thread start

            ResumeThread(pMyIntrInfo->hISTHandle);

                 2. wait for interrupt event

      dwStatus = WaitForSingleObject(pMyIntrInfo->hIntrEvent, INFINITE);

                 3. process IST    res = pMyIntrInfo->pIstFunc(pMyIntrInfo->param);

                 4. finish interrupt to clear the mask of interrupt(OEMInterruptDone)

              InterruptDone(pMyIntrInfo->dwSysIntr);

         then, host can receive the same interrupt again.

  • 相关阅读:
    (Java) LeetCode 44. Wildcard Matching —— 通配符匹配
    (Java) LeetCode 30. Substring with Concatenation of All Words —— 与所有单词相关联的字串
    (Java) LeetCode 515. Find Largest Value in Each Tree Row —— 在每个树行中找最大值
    (Java) LeetCode 433. Minimum Genetic Mutation —— 最小基因变化
    (Java) LeetCode 413. Arithmetic Slices —— 等差数列划分
    (Java) LeetCode 289. Game of Life —— 生命游戏
    (Java) LeetCode 337. House Robber III —— 打家劫舍 III
    (Java) LeetCode 213. House Robber II —— 打家劫舍 II
    (Java) LeetCode 198. House Robber —— 打家劫舍
    (Java) LeetCode 152. Maximum Product Subarray —— 乘积最大子序列
  • 原文地址:https://www.cnblogs.com/yuhui526/p/4057477.html
Copyright © 2011-2022 走看看