socketref,再见!高德

https://github.com/adoggie

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  246 Posts :: 4 Stories :: 312 Comments :: 0 Trackbacks

常用链接

留言簿(54)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜


经常会在编写流驱动接口的时候必须实现一系列的接口,诸如 xxx_init,xxx_open,xxx_write等等,某些接口函数虽然无需功能的实现但也必须定义一个空的函数接口。由于多年的c++思路,利用虚函数(virtual)和重载(override)把这些驱动的实现封装起来,来简化代码量。

程序的实现,采用了两种方式: 宏定义和类继承
希望对编写wince 流驱动的开发人员有所帮助

  1 /*
  2     driverbase.h
  3     scott     2008.1.1
  4     
  5 */
  6 
  7 #ifndef _DRIVERBASE_H
  8 #define _DRIVERBASE_H
  9 
 10 #include <windows.h>
 11 #include <types.h>
 12 #include <excpt.h>
 13 #include <tchar.h>
 14 #include <cardserv.h>
 15 #include <cardapi.h>
 16 #include <tuple.h>
 17 #include <devload.h>
 18 #include <diskio.h>
 19 #include <nkintr.h>
 20 #include <windev.h>
 21 
 22 /**
 23 class SimpleInterruptHandler
 24 example:
 25     New_InterruptHandler(irq12)
 26     New_InterruptHandler(irq13)
 27     class MyDriver:public InterruptHandlerClassName(irq12),public InterruptHandlerClassName(irq13){
 28         public:
 29             void run_irq12(){
 30                 while( !broken_irq12() ){
 31                      //repeate doing interrupt 
 32                 }
 33             }
 34             void run_irq13(){
 35                 
 36             }
 37     }
 38     MyDriver    driver;
 39     driver.set_irq_irq12(IRQ_ADC);
 40     driver.start_irq12();
 41     driver.start_irq13();
 42     driver.stop_irq12();
 43 ========    
 44     driver 能处理多种中断,但是每个中断处理必须消耗一个线程资源
 45 **/
 46 
 47 #define INVALID_IRQ_VALUE 0xffff
 48 #define InterruptHandlerClassName(cls) SimpleInterruptHandler_##cls
 49 #define New_InterruptHandler(cls)    \
 50 class SimpleInterruptHandler_##cls{\
 51 public:\
 52     SimpleInterruptHandler_##cls(){\
 53         set_irq_##cls(INVALID_IRQ_VALUE);    \
 54         _irq_sys = INVALID_IRQ_VALUE;\
 55         _ev_exit = CreateEvent(NULL, TRUE, FALSE, NULL);\
 56         _broken = false;\
 57     }\
 58     ~SimpleInterruptHandler_##cls(){\
 59         CloseHandle(_ev_exit);\
 60     }\
 61     void     set_irq_##cls(DWORD irqhw){\
 62         _irq_hw = irqhw;\
 63     }\
 64     bool     start_##cls(){\
 65         if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &_irq_hw, sizeof(DWORD), &_irq_sys, sizeof(DWORD), NULL)){\
 66               return false;\
 67           }\
 68           _evInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);\
 69           if!_evInterrupt ){\
 70               KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &_irq_sys, sizeof(DWORD), 0, 0, NULL);\
 71               return false;\
 72           }\
 73           if(!InterruptInitialize(_irq_sys,_evInterrupt,NULL,NULL)){\
 74               return false;\
 75           }\
 76           DWORD threadID;\
 77           CreateThread(0, 0, (LPTHREAD_START_ROUTINE) SimpleInterruptHandler_##cls::entry, (LPVOID)this, 0, &threadID);\
 78         return true;\
 79     }\
 80     void     stop_##cls(){\
 81         _broken = true;\
 82         WaitForSingleObject(_ev_exit,INFINITE);\
 83         CloseHandle(_evInterrupt);\
 84         KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &_irq_sys, sizeof(DWORD), 0, 0, NULL);\
 85     }\
 86 protected:\
 87     bool    broken_##cls(){\
 88         return _broken;\
 89     }\
 90     virtual void run_##cls(){}\
 91 private:\
 92     static void entry(void * user){\
 93         SimpleInterruptHandler_##cls* h = (SimpleInterruptHandler_##cls*) user;\
 94         ResetEvent(h->_ev_exit);\
 95         h->_broken = false;\
 96         h->run_##cls();\
 97         SetEvent(h->_ev_exit);\
 98     }\
 99 private:\
100     DWORD     _irq_hw;\
101     DWORD    _irq_sys;\
102     HANDLE    _evInterrupt;\
103     HANDLE    _ev_exit;\
104     bool    _broken;\
105 };
106 
107 
108 // second method, binding function of class
109 // base template interrupt handle
110 class InterruptHandler{
111 public:
112     InterruptHandler(void * user){
113         _irq_sys = INVALID_IRQ_VALUE;
114         _ev_exit = CreateEvent(NULL, TRUE, FALSE, NULL);
115         _broken = false;
116     }
117     ~InterruptHandler(){
118         CloseHandle(_ev_exit);
119     }
120     void *  get_user(){    return _user;}
121     bool    broken(){
122         return _broken;
123     }
124 
125 public:
126     DWORD     _irq_hw;
127     DWORD    _irq_sys;
128     HANDLE    _evInterrupt;
129     HANDLE    _ev_exit;
130     bool    _broken;
131     void *    _user;
132 };
133 
134 template <typename T>
135 class SimpleInterruptHandler:public InterruptHandler{
136 public:
137     SimpleInterruptHandler(T* user):InterruptHandler((void*)user){
138         _entry = NULL;
139     }
140     ~SimpleInterruptHandler(){
141     }
142     void bind_entry( void (T::*entry)(InterruptHandler*) ){
143         _entry = entry;
144     }
145     void set_irq(DWORD irq){     //设置硬件中断编号
146         _irq_hw = irq;
147     }
148     bool     start(){
149         if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &_irq_hw, sizeof(DWORD), &_irq_sys, sizeof(DWORD), NULL)){
150               return false;
151           }
152           _evInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
153           if!_evInterrupt ){
154               KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &_irq_sys, sizeof(DWORD), 0, 0, NULL);
155               return false;
156           }
157           if(!InterruptInitialize(_irq_sys,_evInterrupt,NULL,NULL)){
158               return false;
159           }
160           DWORD threadID;
161           CreateThread(0, 0, (LPTHREAD_START_ROUTINE) SimpleInterruptHandler<T>::entry, (LPVOID)this, 0, &threadID);
162         return true;
163     }
164     void     stop(){
165         _broken = true;
166         WaitForSingleObject(_ev_exit,INFINITE);
167         CloseHandle(_evInterrupt);
168         KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &_irq_sys, sizeof(DWORD), 0, 0, NULL);
169     }
170 private:
171     static void entry(void * user){
172         SimpleInterruptHandler<T>* h = (SimpleInterruptHandler<T>*) user;
173         ResetEvent(h->_ev_exit);
174         
175         h->_broken = false;
176         if( h->_entry ){
177             (((T*)h->_user)->*h->_entry)( h);
178         }
179         SetEvent(h->_ev_exit);    
180     }
181 private:
182     void (T::*_entry)(InterruptHandler*);
183 };
184 
185 
186  
187 
188     
189 
190 //class  StreamDriver 
191 // 流接口设备驱动基础类
192 
193 class StreamDriver{
194 public:
195     StreamDriver(){}
196     virtual ~StreamDriver(){};
197     virtual BOOL Close(DWORD hOpenContext ){
198         return TRUE;
199     }
200     virtual BOOL Deinit(DWORD hDeviceContext ){
201         return TRUE;
202     }
203     virtual DWORD Init(LPCTSTR pContext,LPCVOID lpvBusContext){
204         return DWORD(this);
205     }
206     virtual BOOL IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut ){
207         return TRUE;
208     }
209     virtual DWORD Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode ){
210         return NULL;
211     }
212     virtual void PowerDown(DWORD hDeviceContext ){}
213     virtual void PowerUp(DWORD hDeviceContext ){}
214     virtual BOOL PreClose(DWORD hOpenContext ){
215         return TRUE;
216     }
217     virtual BOOL PreDeinit(DWORD hDeviceContext ){
218         return TRUE;
219     }
220     virtual DWORD Read(DWORD hOpenContext,LPVOID pBuffer,DWORD Count ){
221         return 0;
222     }
223     virtual DWORD Seek(DWORD hOpenContext,long Amount,WORD Type ){
224         return 0;
225     }
226     virtual DWORD Write(DWORD hOpenContext,LPCVOID pBuffer,DWORD Count ){
227         return 0;
228     }
229 private:
230     
231 };
232 
233 #define DRIVER_ENTRY_CLOSE(prefix,pcls)    \
234             BOOL prefix##_Close(DWORD hOpenContext ){\
235                 return pcls->Close(hOpenContext);    \
236             }
237 #define DRIVER_ENTRY_DEINIT(prefix,pcls)    \
238             BOOL prefix##_Deinit(DWORD hDeviceContext ){\
239                 return pcls->Deinit(hDeviceContext);    \
240             }
241 #define DRIVER_ENTRY_INIT(prefix,pcls)    \
242             BOOL prefix##_Init(LPCTSTR pContext,LPCVOID lpvBusContext ){\
243                 return pcls->Init( pContext,lpvBusContext );    \
244             }
245 #define DRIVER_ENTRY_IOCONTROL(prefix,pcls)    \
246             BOOL prefix##_IOControl(DWORD hOpenContext,DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut  ){\
247                 return pcls->IOControl( hOpenContext, dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut );    \
248             }
249 #define DRIVER_ENTRY_OPEN(prefix,pcls)    \
250             BOOL prefix##_Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode ){\
251                 return pcls->Open(hDeviceContext,AccessCode,ShareMode);    \
252             }
253 #define DRIVER_ENTRY_POWERDOWN(prefix,pcls)    \
254             void prefix##_PowerDown(DWORD hOpenContext ){\
255                 pcls->PowerDown(hOpenContext);    \
256             }
257 #define DRIVER_ENTRY_POWERUP(prefix,pcls)    \
258             void prefix##_PowerUp(DWORD hOpenContext ){\
259                  pcls->PowerUp(hOpenContext);    \
260             }
261 #define DRIVER_ENTRY_PRECLOSE(prefix,pcls)    \
262             BOOL prefix##_PreClose(DWORD hOpenContext ){\
263                 return pcls->PreClose(hOpenContext);    \
264             }
265 #define DRIVER_ENTRY_PREDEINIT(prefix,pcls)    \
266             BOOL prefix##_PreDeinit(DWORD hOpenContext ){\
267                 return pcls->PreDeinit(hOpenContext);    \
268             }
269 
270 #define DRIVER_ENTRY_READ(prefix,pcls)    \
271             BOOL prefix##_Read(DWORD hOpenContext,LPVOID pBuffer,DWORD Count ){\
272                 return pcls->Read( hOpenContext, pBuffer, Count);    \
273             }
274 #define DRIVER_ENTRY_SEEK(prefix,pcls)    \
275             BOOL prefix##_Seek(DWORD hOpenContext,long Amount,WORD Type){\
276                 return pcls->Seek( hOpenContext, Amount, Type);    \
277             }
278 #define DRIVER_ENTRY_WRITE(prefix,pcls)    \
279             BOOL prefix##_Write(DWORD hOpenContext,LPCVOID pBuffer,DWORD Count ){\
280                 return pcls->Write( hOpenContext, pBuffer, Count);    \
281             }    
282 
283 #define DRIVER_DLLENTRY    \
284 BOOL DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved){\
285     switch ( dwReason ) {\
286     case DLL_PROCESS_ATTACH:\
287         DisableThreadLibraryCalls((HMODULE) hInstDll);\
288         break;\
289     }\
290     return (TRUE);\
291 }
292                 
293 /**
294     定义流式驱动入口接口函数
295     NEW_DRIVER_ENTRIES(prefix,pcls) 
296     prefix     驱动类别前缀 
297     pcls    必须是StreamDriver的 子类实现对象地址
298     
299 example:
300     class PowerKeyDriver:public StreamDriver{}s
301     PowerKeyDriver pkdrv;
302     NEW_DRIVER_ENTRIES("PWK",&pkdrv);
303  */            
304                                             
305 #define NEW_DRIVER_ENTRIES(prefix,pcls) \
306     DRIVER_ENTRY_CLOSE(prefix,(pcls))\
307     DRIVER_ENTRY_DEINIT(prefix,(pcls))\
308     DRIVER_ENTRY_INIT(prefix,(pcls))\
309     DRIVER_ENTRY_IOCONTROL(prefix,(pcls))\
310     DRIVER_ENTRY_OPEN(prefix,(pcls))\
311     DRIVER_ENTRY_POWERDOWN(prefix,(pcls))\
312     DRIVER_ENTRY_POWERUP(prefix,(pcls))\
313     DRIVER_ENTRY_PRECLOSE(prefix,(pcls))\
314     DRIVER_ENTRY_PREDEINIT(prefix,(pcls))\
315     DRIVER_ENTRY_READ(prefix,(pcls))\
316     DRIVER_ENTRY_SEEK(prefix,(pcls))\
317     DRIVER_ENTRY_WRITE(prefix,(pcls))\
318     DRIVER_DLLENTRY
319 
320 #define DBGMSG(m) RETAILMSG(1,m)
321 
322 #endif
323 

测试代码:
 1 
 2 #include "driverbase.h"
 3 
 4 
 5 //基于宏的中断处理方法
 6 //扩展函数命名实现在容器中自由定义中断处理过程
 7 New_InterruptHandler(touch);
 8 New_InterruptHandler(pwrkey);
 9 class test_interrupt:public InterruptHandlerClassName(touch),public InterruptHandlerClassName(pwrkey){
10 public:
11     void run_touch(){
12         while!broken_touch() ){
13         }
14     }
15     void run_pwrkey(){
16     }
17     void driver_start(){
18         set_irq_touch(10);
19         start_touch();
20     }
21     void driver_terminate(){
22         stop_touch(); // it will block until working thread endding
23     }
24 };
25 
26 
27 
28 class test_drv:public StreamDriver{
29 public:
30     DWORD Init(LPCTSTR pContext,LPCVOID lpvBusContext){
31         DBGMSG( (TEXT("Init::test driver %d"),1));
32         ::MessageBox(NULL,L"Init() Test",L"",MB_OK);
33         return NULL;
34     }
35     BOOL Deinit(DWORD hDeviceContext ){
36         DBGMSG( (TEXT("DeInit::test driver %d"),2));
37         ::MessageBox(NULL,L"DeInit() Test",L"",MB_OK);
38         return TRUE;
39     }
40 };
41 
42 test_drv driver;
43 
44 NEW_DRIVER_ENTRIES(TST,&driver);
45 
46 /*
47 [HKEY_LOCAL_MACHINE\Drivers\BuiltIn_\test]
48    "Order"=dword:0
49    "Prefix"="TST"
50    "Dll"="test.dll"
51    
52    
53 test.dll    $(_FLATRELEASEDIR)\test.dll        NK    SH
54 
55 */
56 
57 //example  3.
58 class MyDriver2{
59 public:
60     MyDriver2():itTouch(this){
61     }
62     void do_irq_touch(InterruptHandler* h){
63         // touch irq will come in
64         //这里判别中断类型等信息
65         while(!h->broken()){
66             //if exception occur or completed, jump out
67             break;
68         }
69     }
70     void start(){
71         itTouch.set_irq(10);
72         itTouch.bind_entry(&MyDriver2::do_irq_touch);
73         itTouch.start();
74     }
75     void stop(){
76         itTouch.stop(); //将等待中断处理线程完全退出
77     }
78 private:
79     SimpleInterruptHandler<MyDriver2> itTouch;
80 };
81 
82 



posted on 2008-05-05 02:15 放屁阿狗 阅读(2085) 评论(0)  编辑 收藏 引用 所属分类: WINCE

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理