Windows CE6.0中断实验过程

WindowsCE6.0中断实验过程

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

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

2.我对WindowsCE6.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(DWORDidInt, //SYSINTR中断号

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

LPVOIDpvData, //传给OEMInterruptEnable缓冲指针

DWORDcbData, //缓冲区的大小

)

然后通过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

typedefstruct{

volatileS3C6410_GPIO_REG*pGPIOregs;

BOOLFlagExitThrd;

}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"

#defineLed1Mask 0x01

#defineLed2Mask 0x02

#defineLed3Mask 0x04

#defineLed4Mask 0x08

#defineLedAllMask 0x0F

#defineButt1Mask 0x01

#defineButt2Mask 0x02

#defineButt3Mask 0x04

#defineButt4Mask 0x08

#defineButt5Mask 0x10

#defineButt6Mask 0x20

static KEY_PUBLIC_CONTEXT *pPublicKey=NULL;

staticvolatileUINT32 dwLedFlag=1;

UINT32g_SysIntr1=0;

UINT32g_SysIntr2=0;

HANDLEg_hEvent1=NULL;

HANDLEg_hThread1=NULL;

HANDLEg_hEvent2=NULL;

HANDLEg_hThread2=NULL;

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

*

* MyKeybuttoneventthread

*

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

INTWINAPIButton1Thread(void)

{

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

while(!pPublicKey->FlagExitThrd)

{

UINT16ch;

RETAILMSG(1,(TEXT("Button1KEY_Read:KEYDeviceReadSuccessfully./r/n")));

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

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

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

WaitForSingleObject(g_hEvent1,INFINITE);

if(pPublicKey->FlagExitThrd)

break;

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

if(dwLedFlag==1)

{

dwLedFlag=0;

pPublicKey->pGPIOregs->GPMDAT|=LedAllMask;

RETAILMSG(1,(TEXT("Button1pressed---LedALLOn:/r/n")));

}

else

{

dwLedFlag=1;

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

RETAILMSG(1,(TEXT("Button1pressed---LedALLOff:/r/n")));

}

InterruptDone(g_SysIntr1);

}

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

return0;

}//Key_Button1Thread()

INTWINAPIButton2Thread(void)

{

DWORDLedNum=1;

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

while(!pPublicKey->FlagExitThrd)

{

UINT16ch;

RETAILMSG(1,(TEXT("Button2KEY_Read:KEYDeviceReadSuccessfully./r/n")));

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

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

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

WaitForSingleObject(g_hEvent2,INFINITE);

if(pPublicKey->FlagExitThrd)

break;

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

if(LedNum==1)

{

LedNum=2;

pPublicKey->pGPIOregs->GPMDAT|=Led1Mask;

RETAILMSG(1,(TEXT("Button2pressed---Led1on:/r/n")));

}

elseif(LedNum==2)

{

LedNum=3;

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

RETAILMSG(1,(TEXT("Button2pressed---Led2On:/r/n")));

}

elseif(LedNum==3)

{

LedNum=4;

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

RETAILMSG(1,(TEXT("Button2pressed---Led3On:/r/n")));

}

elseif(LedNum==4)

{

LedNum=0;

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

RETAILMSG(1,(TEXT("Button2pressed---Led4On:/r/n")));

}

else

{

LedNum=1;

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

RETAILMSG(1,(TEXT("Button2pressed---LedALLoff:/r/n")));

}

InterruptDone(g_SysIntr2);

}

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

return0;

}//Key_Button2Thread()

BOOLKEY_Deinit(DWORDdwContext)

{

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

//informISTexitstatus

pPublicKey->FlagExitThrd=TRUE;

//freevirtualmemory

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);

}

//Waitforthreadstofinish

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_CONTEXTKEY_Init(DWORDdwContext)

{

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

BOOLbResult=TRUE;

DWORDdwHwIntr=0;

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

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

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

{

RETAILMSG(1,(TEXT("[KEY]Can'tnotallocateforKEYContext/n")));

returnNULL;

}

//GPIOVirtualalloc

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

if(pPublicKey->pGPIOregs==NULL)

{

RETAILMSG(1,(TEXT("[KEY]ForpGPIOregs:DrvLib_MapIoSpacefailed!/r/n")));

bResult=FALSE;

gotoCleanUp;

}

//禁止上下拉

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

{

//Button1Thread

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]FailedtorequesttheKEYsysintr./n")));

g_SysIntr1=SYSINTR_UNDEFINED;

bResult=FALSE;

break;

}

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

{

RETAILMSG(1,(TEXT("[KEY]KEYInterruptInitializationfailed!!!/n")));

bResult=FALSE;

break;

}

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

if(g_hThread1==NULL)

{

RETAILMSG(1,(TEXT("[KEY]KeyButtonThreadcreationerror!!!/n")));

bResult=FALSE;

break;

}

//Button2Thread

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]FailedtorequesttheKEYsysintr./n")));

g_SysIntr2=SYSINTR_UNDEFINED;

bResult=FALSE;

break;

}

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

{

RETAILMSG(1,(TEXT("[KEY]KEYInterruptInitializationfailed!!!/n")));

bResult=FALSE;

break;

}

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

if(g_hThread2==NULL)

{

RETAILMSG(1,(TEXT("[KEY]KeyButton2Threadcreationerror!!!/n")));

bResult=FALSE;

break;

}

}while(0);

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

if(bResult)

{

returnpPublicKey;

}

else

{

returnNULL;

}

CleanUp:

if(!bResult)

{

if(pPublicKey->pGPIOregs)

{

DrvLib_UnmapIoSpace((PVOID)pPublicKey->pGPIOregs);

pPublicKey->pGPIOregs=NULL;

}

returnNULL;

}

}

DWORDKEY_Open(DWORDdwData,DWORDdwAccess,DWORDdwShareMode)

{

RETAILMSG(1,(TEXT("KEY_Open:KEYDeviceOpenSuccessfully./r/n")));

return(dwData);

}

BOOLKEY_Close(DWORDHandle)

{

RETAILMSG(1,(TEXT("KEY_Close:KEYDeviceCloseSuccessfully./r/n")));

return(TRUE);

}

DWORDKEY_Read(DWORDHandle,LPVOIDpBuffer,DWORDdwNumBytes)

{

UINT16ch;

DWORDresult;

RETAILMSG(1,(TEXT("KEY_Read:KEYDeviceReadSuccessfully./r/n")));

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

if((ch&Butt1Mask)!=0)

{

result=1;

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

}

elseif((ch&Butt2Mask)!=0)

{

result=2;

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

}

else

{

result=-1;

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

}

dwNumBytes=result;

return(dwNumBytes);

}

DWORDKEY_Write(DWORDHandle,LPCVOIDpBuffer,DWORDdwNumBytes)

{

RETAILMSG(1,(TEXT("BTN_Write:KEYDeviceWriteSuccessfully./r/n")));

return(TRUE);

}

DWORDKEY_Seek(DWORDHandle,longlDistance,DWORDdwMoveMethod)

{

return(DWORD)-1;

}

voidKEY_PowerDown(void)

{

return;

}

voidKEY_PowerUp(void)

{

return;

}

BOOLKEY_IOControl(DWORDhOpenContext,DWORDdwCode,PBYTEpBufIn,DWORDdwLenIn,PBYTEpBufOut,DWORDdwLenOut,PDWORDpdwActualOut)

{

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

return(TRUE);

}

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

*DLL入口函数

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

BOOL

DllEntry(

HINSTANCEhinstDll,

DWORDdwReason,

LPVOIDlpReserved

)

{

if(dwReason==DLL_PROCESS_ATTACH)

{

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

}

if(dwReason==DLL_PROCESS_DETACH)

{

DEBUGMSG(1,(TEXT("[MyKey]ProcessDetach/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

LIBRARYMyKey

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.dllNKSHK

(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.编译建立此驱动。注意:这里只需要编译驱动目录就可以了,不需要重新编译整个系统。

<!--EndFragment-->

你可能感兴趣的:(windows)