1.实验目的:通过本次试验学习Windows CE6.0的中断处理的过程以及熟悉在驱动程序中运行中断的编程。
2.我对Windows CE6.0中断的理解:
Windows® CE将中断处理分成两个步骤:中断服务程序ISR和中断服务线程IST。如果中断被使能,则当中断产生时,内核将调用该中断注册的ISR,ISR执行完后将返回系统中断号,内核检查系统中断号并且设置相关的事件,内核设置相关事件后,相应的IST将开始执行。
3.Windows® CE的处理流程:
(1)如果一个驱动程序要处理一个中断,那么驱动程序首先要建立一个事件(CreateEvent),然后调用InterruptInitialize将该事件与中断号绑定,这一步会使能该中断,OAL中的OEMInerrupteEnable会被调用,如果该函数不返回true的话,InterruptInitialize就会失败。然后驱动程序中的IST就可以使用WaitForSingleObject函数来等待中断的发生。
(2)当一个硬件中断发生之后,操作系统陷入异常,中断向量指示进入CE的异常处理程序,该异常处理程序然后调用OAL的OEMInterruptHandler函数,该函数检测硬件之后,将硬件中断转换为软件的中断号,返回给系统。该中断号就是上面提到的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.c和MyKey.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 #include #include #include #include #include #include #include #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)
上一篇:基于gnu-arm-linux的LPC2220的简单工程模板
下一篇:基于ARM7(LPC2131)平台的μC/OS-Ⅱ的移植
推荐阅读最新更新时间:2026-03-21 10:49
- LM2904DMR2G 函数发生器运算放大器的典型应用
- DEMO9RS08KA2: DEMO9RS08KA2 Demonstration Board
- MCP73871EV,MCP73871 锂离子电池充电器评估板
- STEVAL-IHM039V1,采用 STM32F415 微控制器的双电机控制演示板
- LTC1606CG 演示板、16 位、250ksps ADC
- RT8086B 3.5A、1.2MHz、同步降压转换器的典型应用
- TS4999EIJT 典型应用 免滤波器立体声 2.8 W D 类音频功率放大器,可选择 3D 音效
- LTM4615,采用 15mm-15mm 封装的完整双路和三路输出负载点模块稳压器
- LTC2415-1IGN 24 位 ADC 的典型应用电路使用电阻器阵列在励磁放大器中提供精确匹配
- 使用 Analog Devices 的 LTC1450LIN 的参考设计



Windows API 函数参考手册
VC6编制的命令行运行的曲线绘图程序
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号