zoukankan      html  css  js  c++  java
  • Windows CE6.0中断实验过程

    Windows CE6.0中断实验过程

                            ----利用键盘控制LED的驱动程序

    1.实验目的:通过本次试验学习Windows CE6.0的中断处理的过程以及熟悉在驱动程序中运行中断的编程。

    2.我对Windows CE6.0中断的理解:

    Windows® CE将中断处理分成两个步骤:中断服务程序ISR和中断服务线程IST。如果中断被使能,则当中断产生时,内核将调用该中断注册的ISRISR执行完后将返回系统中断号,内核检查系统中断号并且设置相关的事件,内核设置相关事件后,相应的IST将开始执行。

    3.Windows® CE的处理流程:

    (1)如果一个驱动程序要处理一个中断,那么驱动程序首先要建立一个事件(CreateEvent),然后调用InterruptInitialize将该事件与中断号绑定,这一步会使能该中断,OAL中的OEMInerrupteEnable会被调用,如果该函数不返回true的话,InterruptInitialize就会失败。然后驱动程序中的IST就可以使用WaitForSingleObject函数来等待中断的发生。

    (2)当一个硬件中断发生之后,操作系统陷入异常,中断向量指示进入CE的异常处理程序,该异常处理程序然后调用OALOEMInterruptHandler函数,该函数检测硬件之后,将硬件中断转换为软件的中断号,返回给系统。该中断号就是上面提到的InterruptInitialize中使用的那个中断号。系统得到该中断号之后,就会找到该中断号对应的事件,并唤醒等待相应事件的线程(IST),然后IST就可以在用户态进行中断处理。处理完成之后,IST需要调用InterruptDone来告诉操作系统中断处理结束,操作系统调用OAL中的OEMInterruptDone函数,最后完成中断的处理。

    4.在驱动中安装中断的方法:

    首先, 在驱动中通过 CreateEvent()函数创建一个 Event 内核对象, 然后通过 InterruptInitialize()

    函数负责把某个逻辑中断号与这个 Event 内核对象关联起来。当中断发生时,操作系统负责引发此

    Event 事件,函数的原型如下: 

    InterruptInitialize(DWORD idInt,         // SYSINTR中断号 

                        HANDLE hEvent ,     // 与该中断相关联的事件句柄 

                        LPVOID pvData,      // 传给OEMInterruptEnable缓冲指针   

    DWORD cbData,      // 缓冲区的大小 

                        )

    然后通过 CreatThread()函数来来创建一个线程,在线程函数中用 WaitForSingleObject()来阻塞

    当前的线程,等待某个 Event 内核对象标识的事件发生。当中断发生后,OAL层就会返回逻辑中断,

    与逻辑中断相关联的 Event 事件就会被触发,被阻塞的中断线程函数就会就绪开始工作。 

    InterruptDonce()函数用来告诉操作系统, 对该中断的处理已完成, 操作系统可重新开启该中断。

    5.步骤:

    1.vs2005里面新建一个DLL的子项目MyKey,在F:/WINCE600/PLATFORM/SMDK6410/SRC/DRIVERS/目录下

    2.添加MyKey.cMyKey.h文件,编辑源程序,如下:

    MyKey.h

    #ifndef _MYKEY_H

    #define _MYKEY_H

    #ifdef  __cplusplus

    Extern "C" {

    #endif

    typedef struct { 

        volatile S3C6410_GPIO_REG     *pGPIOregs;

        BOOL   FlagExitThrd; 

    } KEY_PUBLIC_CONTEXT, *PKEY_PUBLIC_CONTEXT;

    #ifdef  __cplusplus

    }

    #endif

    #endif

    MyKey.c

    #include <windows.h>

    #include <nkintr.h>

    #include <pm.h>

    #include <nkintr.h>

    #include <bsp.h>

    #include <s3c6410.h>

    #include <s3c6410_vintr.h>

    #include <DrvLib.h>

    #include "MyKey.h"

    #define Led1Mask  0x01

    #define Led2Mask  0x02

    #define Led3Mask  0x04

    #define Led4Mask  0x08

    #define LedAllMask 0x0F

    #define Butt1Mask  0x01

    #define Butt2Mask  0x02

    #define Butt3Mask  0x04

    #define Butt4Mask  0x08

    #define Butt5Mask  0x10

    #define Butt6Mask  0x20

    static  KEY_PUBLIC_CONTEXT *pPublicKey = NULL;

    static volatile UINT32 dwLedFlag   = 1;

    UINT32 g_SysIntr1 = 0;

    UINT32 g_SysIntr2 = 0;

    HANDLE g_hEvent1 = NULL;

    HANDLE g_hThread1 = NULL;  

    HANDLE g_hEvent2 = NULL;

    HANDLE g_hThread2 = NULL; 

    /******************************************************************************

     *

     * MyKey button event thread

     *

     *******************************************************************************/

    INT WINAPI Button1Thread(void)

    {

    RETAILMSG(1, (TEXT("Button1 Thread Entered ! /r/n")));

        while(!pPublicKey->FlagExitThrd)

        {

    UINT16 ch;

    RETAILMSG(1, (TEXT("Button1 KEY_Read: KEY Device Read Successfully./r/n")));

    ch = (UINT16)pPublicKey->pGPIOregs->GPNDAT;

    RETAILMSG(1,(TEXT("Button1 ReadValue:  0x%x /n"), ch));

        RETAILMSG(1, (TEXT("Button1 Thread ! /r/n"))); 

    WaitForSingleObject(g_hEvent1, INFINITE);

    if(pPublicKey->FlagExitThrd)

    break;

    RETAILMSG(1, (TEXT("Button1 Thread Start Running ! /r/n")));

    if( dwLedFlag == 1 )

    {

    dwLedFlag = 0;

    pPublicKey->pGPIOregs->GPMDAT |= LedAllMask;

    RETAILMSG(1, (TEXT("Button1 pressed---Led ALL On:/r/n")));

    }

    else

    {

    dwLedFlag = 1;

    pPublicKey->pGPIOregs->GPMDAT &= ~LedAllMask;

    RETAILMSG(1, (TEXT("Button1 pressed---Led ALL Off:/r/n")));

    }

    InterruptDone(g_SysIntr1);

        }

        RETAILMSG(1, (TEXT("KEY: KEY Button1Thread Exiting/r/n")));

        return 0;

    } // Key_Button1Thread()

    INT WINAPI Button2Thread(void)

    {

    DWORD LedNum = 1;

    RETAILMSG(1, (TEXT("Button2 Thread Entered ! /r/n")));

        while(!pPublicKey->FlagExitThrd)

        {

    UINT16 ch;

    RETAILMSG(1, (TEXT("Button2 KEY_Read: KEY Device Read Successfully./r/n")));

    ch = (UINT16)pPublicKey->pGPIOregs->GPNDAT;

    RETAILMSG(1,(TEXT("Button2 ReadValue:  0x%x /n"), ch));

        RETAILMSG(1, (TEXT("Button2 Thread ! /r/n"))); 

    WaitForSingleObject(g_hEvent2, INFINITE);

    if(pPublicKey->FlagExitThrd)

    break;

    RETAILMSG(1, (TEXT("Button2 Thread Start Running ! /r/n")));

    if( LedNum == 1 )

    {

    LedNum = 2;

    pPublicKey->pGPIOregs->GPMDAT |= Led1Mask;

    RETAILMSG(1, (TEXT("Button2 pressed---Led 1 on:/r/n")));

    }

    else if ( LedNum == 2 )

    {

    LedNum = 3;

    pPublicKey->pGPIOregs->GPMDAT |= Led2Mask;;

    RETAILMSG(1, (TEXT("Button2 pressed---Led 2 On:/r/n")));

    }

    else if ( LedNum == 3 )

    {

    LedNum = 4;

    pPublicKey->pGPIOregs->GPMDAT |= Led3Mask;;

    RETAILMSG(1, (TEXT("Button2 pressed---Led 3 On:/r/n")));

    }

    else if ( LedNum == 4 )

    {

    LedNum = 0;

    pPublicKey->pGPIOregs->GPMDAT |= Led4Mask;;

    RETAILMSG(1, (TEXT("Button2 pressed---Led 4 On:/r/n")));

    }

    else

    {

    LedNum = 1;

    pPublicKey->pGPIOregs->GPMDAT &= ~LedAllMask;;

    RETAILMSG(1, (TEXT("Button2 pressed---Led ALL off:/r/n")));

    }

    InterruptDone(g_SysIntr2);

        }

        RETAILMSG(1, (TEXT("KEY: KEY Button2Thread Exiting/r/n")));

        return 0;

    } // Key_Button2Thread()

    BOOL KEY_Deinit(DWORD dwContext)

    {

    RETAILMSG(1, (TEXT("KEY_DeInit: dwContext = 0x%x/r/n/n"), dwContext));

    // inform IST exit status

        pPublicKey->FlagExitThrd = TRUE;

    // free virtual memory

    if(pPublicKey->pGPIOregs ) 

    {

    DrvLib_UnmapIoSpace((PVOID)pPublicKey->pGPIOregs);

    pPublicKey->pGPIOregs = NULL;

    }

    if(g_hEvent1)

        {

            SetEvent(g_hEvent1);

            InterruptDisable(g_SysIntr1);

            CloseHandle(g_hEvent1);

        }

    if(g_hEvent2)

        {

            SetEvent(g_hEvent2);

    InterruptDisable(g_SysIntr2);

            CloseHandle(g_hEvent2);

        }

        // Wait for threads to finish

        WaitForSingleObject(g_hThread1, INFINITE);

    if(g_hThread1)

         CloseHandle(g_hThread1);

    WaitForSingleObject(g_hThread2, INFINITE);

        if(g_hThread2)

         CloseHandle(g_hThread2);

    LocalFree(pPublicKey);

        return (TRUE);

    }

    PKEY_PUBLIC_CONTEXT KEY_Init(DWORD dwContext)

    {

    LPTSTR                     ActivePath = (LPTSTR) dwContext; // HKLM/Drivers/Active/xx

        BOOL                       bResult = TRUE;

        DWORD                      dwHwIntr = 0;

    RETAILMSG(1, (TEXT("KEY_Init:dwContext = 0x%x/r/n"), dwContext));

        RETAILMSG(1,(TEXT("[KEY] Active Path : %s/n"), ActivePath));

        if ( !(pPublicKey = (PKEY_PUBLIC_CONTEXT)LocalAlloc( LPTR, sizeof(KEY_PUBLIC_CONTEXT) )) )

        {

            RETAILMSG(1,(TEXT("[KEY] Can't not allocate for KEY Context/n")));

            return NULL;

        }

        // GPIO Virtual alloc

        pPublicKey->pGPIOregs = (volatile S3C6410_GPIO_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_GPIO, sizeof(S3C6410_GPIO_REG), FALSE);

        if (pPublicKey->pGPIOregs == NULL)

        {

            RETAILMSG(1,(TEXT("[KEY] For pGPIOregs: DrvLib_MapIoSpace failed!/r/n")));

            bResult = FALSE;

            goto CleanUp;

        } 

    //禁止上下拉

    pPublicKey->pGPIOregs->GPMPUD = 0x00000000;

    //GPM0-GPM3设置成输出

    pPublicKey->pGPIOregs->GPMCON = 0x00001111;

    //LED0-3熄灭

    pPublicKey->pGPIOregs->GPMDAT = 0x0;

    //设置EINT0中断

    //禁止GPN0GPN1上下拉

    pPublicKey->pGPIOregs->GPNPUD &= ~0x0F;

    //GPN0-1设置成外中断

    pPublicKey->pGPIOregs->GPNCON |= 0x0a;

    //使能外中断EINT0-EINT1

    pPublicKey->pGPIOregs->EINT0MASK &= ~0x3;

    //EINT0-1下降沿触发中断

    pPublicKey->pGPIOregs->EINT0CON0 |= 0x2;

        do

        {

            //Button1 Thread

    pPublicKey->FlagExitThrd = FALSE;

            g_hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);

           

    g_SysIntr1 = SYSINTR_UNDEFINED;

    dwHwIntr = IRQ_EINT0;

    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &g_SysIntr1, sizeof(DWORD), NULL))

            {

                RETAILMSG(1,(TEXT("[KEY] Failed to request the KEY sysintr./n")));

                g_SysIntr1 = SYSINTR_UNDEFINED;

                bResult = FALSE;

                break;

            }

            if (!InterruptInitialize(g_SysIntr1, g_hEvent1, NULL, 0))

            {

                RETAILMSG(1,(TEXT("[KEY] KEY Interrupt Initialization failed!!!/n")));

                bResult = FALSE;

                break;

            }

    g_hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Button1Thread, NULL, 0, NULL);

    if (g_hThread1 == NULL)

            {

                RETAILMSG(1,(TEXT("[KEY] Key Button Thread creation error!!!/n")));

                bResult = FALSE;

                break;

            }

    //Button2 Thread

    g_hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);

           

    g_SysIntr2 = SYSINTR_UNDEFINED;

    dwHwIntr = IRQ_EINT1;

    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &g_SysIntr2, sizeof(DWORD), NULL))

            {

                RETAILMSG(1,(TEXT("[KEY] Failed to request the KEY sysintr./n")));

                g_SysIntr2 = SYSINTR_UNDEFINED;

                bResult = FALSE;

                break;

            }

            if (!InterruptInitialize(g_SysIntr2, g_hEvent2, NULL, 0))

            {

                RETAILMSG(1,(TEXT("[KEY] KEY Interrupt Initialization failed!!!/n")));

                bResult = FALSE;

                break;

            }

    g_hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Button2Thread, NULL, 0, NULL);

    if (g_hThread2 == NULL)

            {

                RETAILMSG(1,(TEXT("[KEY] Key Button2 Thread creation error!!!/n")));

                bResult = FALSE;

                break;

            }

        } while (0);

        RETAILMSG(1,(TEXT("--[KEY] KEY_Init Function/r/n")));

        if(bResult)

        {

            return pPublicKey;

        }

        else

        {

            return NULL;

        }

    CleanUp:

        if (!bResult)

        {

            if (pPublicKey->pGPIOregs)

            {

                DrvLib_UnmapIoSpace((PVOID)pPublicKey->pGPIOregs);

                pPublicKey->pGPIOregs = NULL;

            }

    return NULL;

    }

    }

    DWORD KEY_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)

    {

    RETAILMSG(1, (TEXT("KEY_Open: KEY Device Open Successfully./r/n")));

        return(dwData);

    }

    BOOL KEY_Close(DWORD Handle)

    {

    RETAILMSG(1, (TEXT("KEY_Close: KEY Device Close Successfully./r/n")));

    return (TRUE);

    }

    DWORD KEY_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)

    {

    UINT16 ch;

    DWORD result;

    RETAILMSG(1, (TEXT("KEY_Read: KEY Device Read Successfully./r/n")));

        ch = (UINT16)pPublicKey->pGPIOregs->GPNDAT;

    if( (ch & Butt1Mask) != 0)

    {

    result = 1;

    RETAILMSG(1, (TEXT("Button 1 pressed:/r/n")));

    }

    else if( (ch & Butt2Mask) != 0)

    {

    result = 2;

    RETAILMSG(1, (TEXT("Button 2 pressed:/r/n")));

    }

    else

    {

    result = -1;

    RETAILMSG(1, (TEXT("No Button pressed:/r/n")));

    }

    dwNumBytes = result;

        return (dwNumBytes);

    }

    DWORD KEY_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)

    {

    RETAILMSG(1, (TEXT("BTN_Write:KEY Device Write Successfully./r/n")));

        return(TRUE);

    }

    DWORD KEY_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)

    {

        return (DWORD)-1;

    }

    void KEY_PowerDown(void)

    {

        return;

    }

    void KEY_PowerUp(void)

    {

    return;

    }

    BOOL KEY_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)

    {

    RETAILMSG(1, (TEXT("BTN_IOControl:/r/n")));

        return(TRUE);

    }

    /*******************************************************************************

     *DLL入口函数

     *******************************************************************************/

    BOOL

    DllEntry(

        HINSTANCE   hinstDll,

        DWORD       dwReason,

        LPVOID      lpReserved

        )

    {

        if ( dwReason == DLL_PROCESS_ATTACH )

        {

            DEBUGMSG (1, (TEXT("[MyKey] Process Attach/r/n")));

        }

        if ( dwReason == DLL_PROCESS_DETACH )

        {

            DEBUGMSG (1, (TEXT("[MyKey] Process Detach/r/n")));

        }

        return(TRUE);

    }

    3.编写配置文件,包括如下文件sourcesMyKey.defmakefile如下:

    技巧:可以到其他驱动程序目录下拷贝在加以修改

    Sources

    RELEASETYPE=PLATFORM

    PREPROCESSDEFFILE=1

    TARGETNAME=MyKey

    TARGETTYPE=DYNLINK

    DEFFILE=MyKey.def

    DLLENTRY=DllEntry

     

    TARGETLIBS= /

        $(_PROJECTROOT)/cesysgen/sdk/lib/$(_CPUINDPATH)/coredll.lib /

        $(_TARGETPLATROOT)/lib/$(_CPUINDPATH)/DriverLib.lib

    SOURCES= /

        MyKey.c

    MyKey.def

    LIBRARY MyKey

    EXPORTS         

            KEY_Init

            KEY_Deinit

            KEY_Open

            KEY_Close

            KEY_Read

            KEY_Write

            KEY_Seek

            KEY_IOControl

            KEY_PowerDown

            KEY_PowerUp

    Makefile

    !INCLUDE $(_MAKEENVROOT)/makefile.def

    4.修改整体项目的配置文件,以便加入我们的驱动到系统中

    (1)platform.bib文件:添加如下一句到文件的合适位置

     MyKey.dll            $(_FLATRELEASEDIR)/MyKey.dll        NK    SHK

    (2)Platform.reg注册表文件:添加如下

    [HKEY_LOCAL_MACHINE/Drivers/BuiltIn/MyKey]

    "Prefix"="KEY"

    "DLL"="MyKey.dll"

    "Order"=dword:4

    "Index"=dword:1

    (3)。修改上层目录的Dirs文件,根据需要添加如下一句:

    DIRS=/

    DrvLib/

    . . .

    WIFI_SDIO/

    MyKey 注:这是添加到此文件的内容。

    5.编译建立此驱动。注意:这里只需要编译驱动目录就可以了,不需要重新编译整个系统。

     

  • 相关阅读:
    poj2752Seek the Name, Seek the Fame【kmp next数组应用】
    poj1961Period【kmp next数组】
    poj2406(kmp next数组)
    KMP原理
    0529
    0428
    2045年4月25日
    0421
    黄金连分数【大数】
    学习linux内核时常碰到的汇编指令(1)
  • 原文地址:https://www.cnblogs.com/brucewoo/p/2252040.html
Copyright © 2011-2022 走看看