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