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.

  • 相关阅读:
    SRM 582 Div II Level Three: ColorTheCells, Brute Force 算法
    SRM 583 Div II Level One:SwappingDigits
    SRM 583 Div Level Two:IDNumberVerification
    [置顶] gis海量资源网盘提供VIP账号无广告高速下载 (更新更多资源)
    为什么必须是final的呢?
    SRM 583 Div II Level Three:GameOnABoard,Dijkstra最短路径算法
    【学习opencv第七篇】图像的阈值化
    quartz 2.1学习(一)
    [置顶] C++之TinyXML的使用介绍
    写个小程序来比对两个目录下的不同文件
  • 原文地址:https://www.cnblogs.com/yuhui526/p/4057477.html
Copyright © 2011-2022 走看看