该按键驱动摘自WINCE的FM1702读写器中的按键代码,按键中断的触发将会通过发送消息传递到标题为“FM1702测试界面[wenziqi@hotmail.com]”的对话框中。
该按键驱动是使用C语言编程,属于WINCE驱动的标准写法,可以作为大家参考的例子!
代码
1 /*******************************************************
2 *作 者:温子祺
3 *联系方式:wenziqi@hotmail.com
4 *说 明:按键驱动
5 *******************************************************/
6
7 #include <windows.h>
8 #include <nkintr.h>
9
10 #include <winreg.h>
11 #include <winioctl.h>
12 #include <ceddk.h>
13 #include <devload.h>
14 #include <S3C2440A.h>//S3C2440包含了自身硬件资源的所有头文件
15 //包括寄存器、逻辑中断号
16 #include "WZQKey.h"
17
18 #pragma comment(lib,"ceddk.lib")
19
20 #define EN_KEY_MSG (1)
21 #if EN_KEY_MSG
22 #define KEYMSG RETAILMSG
23 #else
24 #define KEYMSG(x,y) (void)0
25 #endif
26
27
28 BOOL WINAPI DllEntry(HANDLE hinstDLL,
29 DWORD dwReason,
30 LPVOID /* lpvReserved */)
31 {
32 switch (dwReason)
33 {
34 case DLL_PROCESS_ATTACH:
35 DEBUGREGISTER((HINSTANCE)hinstDLL);
36 return TRUE;
37 case DLL_THREAD_ATTACH:
38 break;
39 case DLL_THREAD_DETACH:
40 break;
41 case DLL_PROCESS_DETACH:
42 break;
43 #ifdef UNDER_CE
44 case DLL_PROCESS_EXITING:
45 break;
46 case DLL_SYSTEM_STARTED:
47 break;
48 #endif
49 }
50
51 return TRUE;
52 }
53 /*
54 ================================================================================
55
56 基本函数接口
57
58 ================================================================================
59 */
60
61
62
63 static PVOID HalRegisterAlloc(PVOID pvRegisterAddress,
64 INT32 nSizeOfReg);
65
66 static DWORD KEYIST (LPVOID lpContext);
67 static BOOL KEYInit (PKEY_CONTEXT pKEY);
68 static BOOL KEYDeinit (PKEY_CONTEXT pKEY);
69 static VOID KEYInterruptEnable (VOID);
70 static VOID KEYInterruptDisable (VOID);
71 static DWORD KEYIST (LPVOID lpContext);
72
73
74 /******************************************************
75 *文件名称:HalRegisterAlloc
76 *输 入:pvRegisterAddress 寄存器地址
77 nSizeOfReg 寄存器占用空闲大小
78 *输 出:分配好的内存指针
79 *功能说明:分配内存
80 *******************************************************/
81 static PVOID HalRegisterAlloc(PVOID pvRegisterAddress,
82 INT32 nSizeOfReg)
83 {
84 PVOID pReg;
85
86 pReg=(PVOID)VirtualAlloc(0,nSizeOfReg,MEM_RESERVE,PAGE_NOACCESS);
87
88 if (pReg)
89 {
90 if(!(VirtualCopy(pReg,
91 (PVOID)((UINT32)pvRegisterAddress>>8),
92 nSizeOfReg,
93 PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE
94 )))
95 {
96 VirtualFree(pReg,0,MEM_RELEASE);
97
98 pReg=NULL;
99 }
100
101 }
102
103 return pReg;
104 }
105
106 static BOOL KEYInterruptEnable(PKEY_CONTEXT pKEY)
107 {
108 if (NULL == pKEY)
109 {
110 return FALSE;
111 }
112
113 pKEY->pIOPortReg->GPGCON = (pKEY->pIOPortReg->GPGCON & ~(0x3 << 0x0))| (0x2 << 0x0); // GPG0 == EINT8
114 pKEY->pIOPortReg->EXTINT1 = (pKEY->pIOPortReg->EXTINT1 & ~(0x7<< 0)) | (0x2 << 0);
115
116 pKEY->pIOPortReg->GPGCON = (pKEY->pIOPortReg->GPGCON & ~(0x3 << 6)) | (0x2 << 6); // GPG3 == EINT11
117 pKEY->pIOPortReg->EXTINT1 = (pKEY->pIOPortReg->EXTINT1 & ~(0x7<< 12)) | (0x2 << 12);
118
119 pKEY->pIOPortReg->GPGCON = (pKEY->pIOPortReg->GPGCON & ~(0x3 << 10)) | (0x2 << 10); // GPG5 == EINT13
120 pKEY->pIOPortReg->EXTINT1 = (pKEY->pIOPortReg->EXTINT1 & ~(0x7<< 20)) | (0x2 << 20);
121
122 pKEY->pIOPortReg->GPGCON = (pKEY->pIOPortReg->GPGCON & ~(0x3 << 12)) | (0x2 << 12); // GPG6 == EINT14
123 pKEY->pIOPortReg->EXTINT1 = (pKEY->pIOPortReg->EXTINT1 & ~(0x7<< 24)) | (0x2 << 24);
124
125 pKEY->pIOPortReg->GPGCON = (pKEY->pIOPortReg->GPGCON & ~(0x3 << 14)) | (0x2 << 14); // GPG7 == EINT15
126 pKEY->pIOPortReg->EXTINT1 = (pKEY->pIOPortReg->EXTINT1 & ~(0x7<< 28)) | (0x2 << 28);
127
128 pKEY->pIOPortReg->GPGCON = (pKEY->pIOPortReg->GPGCON & ~(0x3 << 22)) | (0x2 << 22); // GPG11 == EINT19
129 pKEY->pIOPortReg->EXTINT2 = (pKEY->pIOPortReg->EXTINT2 & ~(0x7<< 12)) | (0x2 << 12);
130
131 return TRUE;
132 }
133
134 static BOOL KEYInterruptDisable(PKEY_CONTEXT pKEY)
135 {
136 if (NULL == pKEY)
137 {
138 return FALSE;
139 }
140
141 pKEY->pIOPortReg->GPGCON = pKEY->pIOPortReg->GPGCON & ~(0x3 << 0); // GPG0 == EINT8
142 pKEY->pIOPortReg->GPGCON = pKEY->pIOPortReg->GPGCON & ~(0x3 << 6); // GPG3 == EINT11
143 pKEY->pIOPortReg->GPGCON = pKEY->pIOPortReg->GPGCON & ~(0x3 << 10); // GPG5 == EINT13
144 pKEY->pIOPortReg->GPGCON = pKEY->pIOPortReg->GPGCON & ~(0x3 << 12); // GPG6 == EINT14
145 pKEY->pIOPortReg->GPGCON = pKEY->pIOPortReg->GPGCON & ~(0x3 << 14); // GPG7 == EINT15
146 pKEY->pIOPortReg->GPGCON = pKEY->pIOPortReg->GPGCON & ~(0x3 << 22); // GPG11 == EINT19
147
148 return TRUE;
149 }
150
151
152
153 static BOOL KEYInit(PKEY_CONTEXT pKEY)
154 {
155 if (NULL == pKEY)
156 {
157 return FALSE;
158 }
159
160 pKEY->pIOPortReg=(volatile S3C2440A_IOPORT_REG *)HalRegisterAlloc((PVOID)S3C2440A_BASE_REG_PA_IOPORT,
161 sizeof(S3C2440A_IOPORT_REG));
162
163 if (pKEY->pIOPortReg == NULL)
164 {
165 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]:Unable to alloc for ioport reg\n")));
166
167 goto init_error;
168 }
169
170 pKEY->pIntrReg=(volatile S3C2440A_INTR_REG *)HalRegisterAlloc((PVOID)S3C2440A_BASE_REG_PA_INTR,
171 sizeof(S3C2440A_INTR_REG));
172
173 if (pKEY->pIntrReg == NULL)
174 {
175 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]Unable to alloc for intrrrupt reg\n")));
176
177 goto init_error;
178 }
179
180 //中断初始化
181 if ((pKEY->hISTEvent=CreateEvent(NULL,FALSE,FALSE,NULL))==NULL)
182 {
183 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]:CreateEvent for ist fail\n")));
184
185 goto init_error;
186 }
187
188 UINT32 unIRQTbl[6] ={IRQ_EINT8,IRQ_EINT11,IRQ_EINT13,IRQ_EINT14,IRQ_EINT15,IRQ_EINT19};
189 UINT32 i;
190
191 for (i=0; i<6; i++)
192 {
193 if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
194 &unIRQTbl[i],
195 sizeof(UINT32),
196 &pKEY->unKeyLogicNumTbl[i],
197 sizeof(UINT32),
198 NULL))
199 {
200 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]:get logic number fail\n")));
201
202 goto init_error;
203 }
204 }
205
206 for (i=0; i<6; i++)
207 {
208 if (!InterruptInitialize(pKEY->unKeyLogicNumTbl[i],
209 pKEY->hISTEvent,
210 NULL,
211 0))
212 {
213 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]:init logic number and event fail\n")));
214
215 goto init_error;
216 }
217 }
218
219 pKEY->bIsKeyThreadValid=TRUE;
220
221 if ((pKEY->hISTThread=CreateThread(NULL,
222 0,
223 KEYIST,
224 (LPVOID)pKEY,
225 0,
226 NULL))==NULL)
227 {
228 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]:CreateThread for key fail\n")));
229
230 goto init_error;
231 }
232
233 for (i=0; i<6; i++)
234 {
235 InterruptDone(pKEY->unKeyLogicNumTbl[i]);
236 }
237
238 if (!CeSetThreadPriority(pKEY->hISTThread,88))
239 {
240 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]:CeSetThreadPriority for key fail\n")));
241
242 goto init_error;
243 }
244
245 KEYInterruptEnable(pKEY);
246
247
248 KEYMSG(KEYDBG,(TEXT("KEYInit[MSG]:Key init OK\n")));
249
250 return TRUE;
251
252 init_error:
253
254 KEYDeinit(pKEY);
255
256 KEYMSG(KEYDBG,(TEXT("KEYInit[ERROR]:Key init fail\n")));
257
258 return FALSE;
259 }
260
261 static BOOL KEYDeinit(PKEY_CONTEXT pKEY)
262 {
263 if (NULL == pKEY)
264 {
265 return FALSE;
266 }
267
268 int i=0;
269
270 for (i=0; i<6; i++)
271 {
272 InterruptDisable(pKEY->unKeyLogicNumTbl[i]);
273 }
274
275 if (pKEY->hISTEvent)
276 {
277 CloseHandle(pKEY->hISTEvent);
278
279 pKEY->hISTEvent=NULL;
280 }
281
282 if (pKEY->hISTThread)
283 {
284 CloseHandle(pKEY->hISTThread);
285
286 pKEY->hISTThread=NULL;
287
288 }
289
290
291 KEYInterruptDisable(pKEY);
292
293 Sleep(1);
294
295 if (pKEY->pIOPortReg)
296 {
297 VirtualFree((LPVOID)pKEY->pIOPortReg,sizeof(S3C2440A_IOPORT_REG),MEM_RELEASE);
298
299 pKEY->pIOPortReg=NULL;
300 }
301
302 if (pKEY->pIntrReg)
303 {
304 VirtualFree((LPVOID)pKEY->pIntrReg, sizeof(S3C2440A_INTR_REG),MEM_RELEASE);
305
306 pKEY->pIntrReg=NULL;
307
308 }
309
310 Sleep(1);
311
312 LocalFree(pKEY);
313
314 KEYMSG(KEYDBG,(TEXT("KEYDeinit[MSG]:Key deinit OK\n")));
315
316 return TRUE;
317 }
318
319 static DWORD KEYIST(LPVOID lpContext)
320 {
321 PKEY_CONTEXT pKEY = (PKEY_CONTEXT)lpContext;
322
323 HWND hWnd=NULL;
324
325 COPYDATASTRUCT cdsKey;
326 cdsKey.cbData = 0;
327 cdsKey.lpData = NULL;
328
329 CONST UCHAR ucKeyDatIndexTbl[6]={ 0, 3, 5, 6, 7, 11};
330 CONST UCHAR ucKeyMskIndexTbl[6]={ 8, 11, 13, 14, 15, 19};
331
332 int i;
333
334 while (pKEY->bIsKeyThreadValid)
335 {
336 if (WAIT_OBJECT_0 == WaitForSingleObject(pKEY->hISTEvent,INFINITE))
337 {
338 ResetEvent(pKEY->hISTEvent);
339
340 Sleep(20); //按键去抖
341
342 cdsKey.dwData = 0;
343
344 KEYMSG(KEYDBG,(TEXT("KEYIST[MSG]:Key found\n")));
345
346 for (i=0; i<6; i++)
347 {
348 if (!(pKEY->pIOPortReg->GPGDAT & (1 << ucKeyDatIndexTbl[i])))
349 {
350 cdsKey.dwData|=1<<i;
351 }
352
353 if (pKEY->pIOPortReg->EINTMASK & (1<< ucKeyMskIndexTbl[i]))
354 {
355 InterruptDone(pKEY->unKeyLogicNumTbl[i]);
356 }
357 }
358
359 hWnd = ::FindWindow(_T("Dialog"),_T("FM1702测试界面[wenziqi@hotmail.com]"));
360
361 if (hWnd)
362 {
363 if (cdsKey.dwData)
364 {
365 #if 1
366 for (i=0; i<6; i++)
367 {
368 if (cdsKey.dwData & (1<<i))
369 {
370 KEYMSG(KEYDBG,(TEXT("KEYIST[MSG]:KEY%d is Pressed!\n"),i));
371 }
372 }
373 #endif
374
375 ::SendMessage(hWnd,WM_COPYDATA, NULL, (LPARAM)&cdsKey);
376 }
377
378 }
379 else
380 {
381 KEYMSG(KEYDBG,(TEXT("KEYIST[ERROR]:Can't find Dialog!\n")));
382 }
383 }
384
385 }
386
387 Sleep(1);
388
389 KEYMSG(KEYDBG,(TEXT("KEYIST[MSG]:Key IST exit\n")));
390
391 return 1;
392 }
393 #if 0
394
395 typedef struct _REG_DRIVER_INFO
396 {
397 //字符串
398 WCHAR DrAuthor[32];
399 WCHAR DrName[32];
400 WCHAR DrPrefix[32];
401 WCHAR DrPath[64];
402
403 //数值
404 WORD DrIndex;
405 WORD DrOrder;
406
407 }REG_DRIVER_INFO,*PREG_DRIVER_INFO;
408
409
410 BOOL RegisterDriver(REG_DRIVER_INFO RegDriverInfo)
411 {
412 DWORD dwRegDataSize=0;
413 DWORD dwRegKeyType=0;
414 DWORD dwRegError=0;
415 HKEY hRegKey=NULL;
416
417 RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegDriverInfo.DrPath, 0,0,&hRegKey);
418
419 if (hRegKey == NULL)
420 {
421 RETAILMSG(1,(TEXT(" \r\nFail to open device key\r\n")));
422
423 goto register_error;
424 }
425
426 dwRegDataSize=sizeof(RegDriverInfo.DrAuthor);
427
428 dwRegKeyType=REG_SZ;
429
430 dwRegError=RegSetValueEx(hRegKey,
431 TEXT("Authro"),
432 NULL,
433 dwRegKeyType,
434 (PBYTE)&RegDriverInfo.DrAuthor,
435 dwRegDataSize);
436
437 if (dwRegDataSize != ERROR_SUCCESS)
438 {
439 RETAILMSG(1,(TEXT("\r\nfail to set author info\r\n")));
440
441 goto register_error;
442 }
443
444 dwRegDataSize=sizeof(RegDriverInfo.DrName);
445
446 dwRegKeyType=REG_SZ;
447
448
449 dwRegError=RegSetValueEx(hRegKey,
450 TEXT("Dll"),
451 NULL,
452 dwRegKeyType,
453 (PBYTE)&RegDriverInfo.DrName,
454 dwRegDataSize);
455
456 if (dwRegError != ERROR_SUCCESS)
457 {
458 RETAILMSG(1,(TEXT(" \r\nFail to set dll name info\r\n")));
459
460 goto register_error;
461 }
462
463 dwRegDataSize=sizeof(RegDriverInfo.DrPrefix);
464
465 dwRegKeyType=REG_SZ;
466
467
468 dwRegError=RegSetValueEx(hRegKey,
469 TEXT("Prefix"),
470 NULL,
471 dwRegKeyType,
472 (PBYTE)&RegDriverInfo.DrPrefix,
473 dwRegDataSize);
474
475 if (dwRegError != ERROR_SUCCESS)
476 {
477 RETAILMSG(1,(TEXT(" \r\nFail to set driver prefix info\r\n")));
478
479 goto register_error;
480 }
481
482
483 dwRegDataSize=sizeof(RegDriverInfo.DrIndex);
484
485 dwRegKeyType=REG_DWORD_LITTLE_ENDIAN;
486
487
488 dwRegError=RegSetValueEx(hRegKey,
489 TEXT("Index"),
490 NULL,
491 dwRegKeyType,
492 (PBYTE)&RegDriverInfo.DrIndex,
493 dwRegDataSize);
494
495 if (dwRegError != ERROR_SUCCESS)
496 {
497 RETAILMSG(1,(TEXT(" \r\nFail to set author info\r\n")));
498
499 goto register_error;
500 }
501
502 dwRegDataSize=sizeof(RegDriverInfo.DrOrder);
503
504 dwRegKeyType=REG_DWORD_LITTLE_ENDIAN;
505
506
507 dwRegError=RegSetValueEx(hRegKey,
508 TEXT("Order"),
509 NULL,
510 dwRegKeyType,
511 (PBYTE)&RegDriverInfo.DrOrder,
512 dwRegDataSize);
513
514 if (dwRegError != ERROR_SUCCESS)
515 {
516 RETAILMSG(1,(TEXT(" \r\nFail to set author info\r\n")));
517
518 goto register_error;
519 }
520
521
522 return TRUE;
523
524
525 register_error:
526
527
528 RegCloseKey(hRegKey);
529
530 return FALSE;
531
532 }
533 #endif
534
535 /*
536 ================================================================================
537
538 DLL 输出函数
539
540 ================================================================================
541 */
542
543
544 PKEY_CONTEXT KEY_Init (PVOID Context)
545 {
546 LPTSTR szActivePath = (LPTSTR)Context; //HKLM\Drivers\Active\xx
547
548 KEYMSG(KEYDBG,(TEXT("KEYInit[MSG]:(%s)\n"),szActivePath));//打印注册路径
549
550 PKEY_CONTEXT pKEY=(PKEY_CONTEXT)LocalAlloc(LPTR,sizeof(KEY_CONTEXT));
551
552 if (NULL == pKEY)
553 {
554 return NULL;
555 }
556
557 #if 1
558 if (!KEYInit(pKEY))
559 {
560 goto init_error;
561
562 }
563 #endif
564
565 #if 0
566 REG_DRIVER_INFO RegDriverInfo={
567 {TEXT("温子祺")}, //Authror
568 {TEXT("WZQKey.dll")}, //Dll
569 {TEXT("KEY")}, //Prefix
570 {TEXT("Drivers\\BuiltIn\\WZQKey")}, //Register Path
571 {1}, //Index
572 {100} //Order
573 };
574
575
576 RegisterDriver(RegDriverInfo);
577 #endif
578 return pKEY;
579
580 init_error:
581
582 KEYDeinit(pKEY);
583
584 return NULL;
585 }
586
587 BOOL KEY_Deinit (PKEY_CONTEXT pKEY)
588 {
589 KEYDeinit(pKEY);;
590
591 return TRUE;
592 }
593
594 PKEY_CONTEXT KEY_Open (PKEY_CONTEXT pKEY,DWORD AccessCode,DWORD ShareMode)
595 {
596 return pKEY;
597 }
598
599 BOOL KEY_Close (PKEY_CONTEXT pKEY)
600 {
601 return TRUE;
602 }
603
604 DWORD KEY_Read (PKEY_CONTEXT pKEY,LPVOID lpOutputBuf,DWORD dwNumOfBytes)
605 {
606 return (DWORD)-1;
607 }
608
609 DWORD KEY_Seek (PVOID Context,long lAmount,DWORD dwType)
610 {
611 return (DWORD)-1;
612 }
613
614 DWORD KEY_Write (PKEY_CONTEXT pKEY,LPVOID lpInPutBuf,DWORD dwNumOfBytes)
615 {
616 return (DWORD)-1;
617 }
618
619 BOOL KEY_IOControl (PKEY_CONTEXT pKEY,
620 DWORD dwCode,
621 PBYTE pBufIn,
622 DWORD dwLenIn,
623 PBYTE pBufOut,
624 DWORD dwLenOut,
625 PDWORD pdwActualOut)
626 {
627 return FALSE;
628 }
629
630 BOOL KEY_PowerUp (PVOID Context)
631 {
632 return TRUE;
633 }
634
635 BOOL KEY_PowerDown (PVOID Context)
636 {
637 return TRUE;
638 }
转载请注明出处,谢谢。