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.

  • 相关阅读:
    C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制
    如何将CKeditor编辑器的上传和thinkphp结合
    在 VisualStudio 给文件起一个带分号的文件名会怎样
    dotnet ConditionalWeakTable 的底层原理
    GitHub 的 Action 判断仅在主仓库才执行脚本
    ASP.NET Core 将文件夹内容输出为压缩包文件方法
    dotnet Microsoft.Recognizers.Text 超强大的自然语言关键词提取库
    dotnet CBB 为什么决定推送 Tag 才能打包
    WPF 通过 InputManager 模拟调度触摸事件
    如何参与 .NET 的开发和设计
  • 原文地址:https://www.cnblogs.com/yuhui526/p/4057477.html
Copyright © 2011-2022 走看看