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.

  • 相关阅读:
    operator模块和functools模块
    函数注解
    用户定义的可调用类型、从定位参数到仅限关键字参数
    可调用对象
    nxos启动的初始化和https访问nx-api
    网络安全基础之网络协议与安全威胁
    华为AC中服务集命令解释配置
    转:图解ARP协议(四)代理ARP原理与实践(“善意的欺骗”)
    windows下python3 python2 共存下安装virtualenvwrapper
    关于网络安全学习的网站
  • 原文地址:https://www.cnblogs.com/yuhui526/p/4057477.html
Copyright © 2011-2022 走看看