如何开发一个WinCE 6的流设备驱动
2009-06-26 09:44
579 查看
在BSP的Drivers目录下,创建新驱动程序的目录,比如MyDriver
修改dirs文件,在变量DIRS中增加新目录MyDriver
创建文件Sources,内容如下:
创建文件Makefile.inc,内容如下:
创建文件MyDriver.def,内容如下:
创建文件MyDriver.c,内容如下:
在platform.bib或者project.bib中,加入此驱动:
在platform.reg或者project.reg中,设置此驱动为BuildIn类型,自动加载:
至此,一个没有实现任何功能的驱动完成了,下面描述如何在驱动中使用中断。
创建中断线程函数(IST),在线程中申请并等待中断:
驱动Dll被加载后,系统首先调用DllEntry,随后调用XXX_Init。修改XXX_Init,加入线程启动代码:
如果驱动只需要处理一个中断,WaitForSingleObject可以处理得很好,如果有多个中断需要处理时,能依葫芦画瓢,创建多个event,每个event注册一个中断,然后使用WaitForMultipleObjects吗?很遗憾,虽然WinCE支持WaitForMultipleObjects,但对于注册到中断的event,只允许等待一个,考虑到中断处理程序所要求的高性能,为了避免进入死锁,当event数目大于1时,WaitForMultipleObjects将会失败,GetLastError返回参数无效的错误代码(是的,如果只有一个event,WaitForMultipleObjects仍然会成功)。
在这种情况下,一种解决方法是,创建多个IST,每个IST处理一个中断。
此外,还有另一种更好的方法,就是把同一个event注册到多个中断,然后使用WaitForSingleObject等待此event,每个中断被触发时,event都会获得信号:
(参考了Bruce Eitman的文章,http://geekswithblogs.net/BruceEitman/Default.aspx)
修改dirs文件,在变量DIRS中增加新目录MyDriver
创建文件Sources,内容如下:
TARGETNAME=MyDriver RELEASETYPE=PLATFORM TARGETTYPE=DYNLINK DEFFILE=MyDriver.def DLLENTRY=DllEntry TARGETLIBS= $(_COMMONSDKROOT)/lib/$(_CPUINDPATH)/coredll.lib SOURCES=MyDriver.c
创建文件Makefile.inc,内容如下:
# # DO NOT EDIT THIS FILE!!! Edit ./sources. if you want to add a new source # file to this component. This file merely indirects to the real make file # that is shared by all the components of Windows CE. # !INCLUDE $(_MAKEENVROOT)/makefile.def
创建文件MyDriver.def,内容如下:
LIBRARY MyDriver EXPORTS XXX_Init XXX_Deinit XXX_Open XXX_Close XXX_Read XXX_Write XXX_Seek XXX_PowerDown XXX_PowerUp XXX_IOControl
创建文件MyDriver.c,内容如下:
#include <windows.h> #include <Devload.h> BOOL XXX_Deinit(DWORD hDeviceContext) { return TRUE; } DWORD XXX_Init(ULONG RegistryPath) { HKEY hKey; RETAILMSG(1, (TEXT("XXX_Init/n"))); hKey = OpenDeviceKey((LPCTSTR) RegistryPath); if(!hKey) { RETAILMSG(1, (TEXT("Failed to open devkeypath,/r/n"))); } else { /* Read values from registry if needed */ RegCloseKey(hKey); } return TRUE; } BOOL WINAPI DllEntry(HINSTANCE DllInstance, ULONG Reason, LPVOID Reserved) { RETAILMSG(1, (TEXT("MyDriver: DllEntry/n"))); return TRUE; } VOID XXX_PowerUp(DWORD hDeviceContext) { } VOID XXX_PowerDown(DWORD hDeviceContext) { } DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode) { return hDeviceContext; } BOOL XXX_Close(DWORD hOpenContext) { return TRUE; } DWORD XXX_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count) { return 0; } DWORD XXX_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes) { return 0; } DWORD XXX_Seek(DWORD hOpenContext, long Amount, DWORD Type) { return 0; } BOOL XXX_IOControl ( DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut ) { BOOL RetVal = TRUE; switch(dwCode) { default: RetVal = FALSE; break; } return RetVal; }
在platform.bib或者project.bib中,加入此驱动:
MyDriver.dll $(_FLATRELEASEDIR)/MyDriver.dll NK K
在platform.reg或者project.reg中,设置此驱动为BuildIn类型,自动加载:
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/MyDriver] "Dll"="MyDriver.dll" "Order"=dword:4 "Prefix"="XXX"
至此,一个没有实现任何功能的驱动完成了,下面描述如何在驱动中使用中断。
创建中断线程函数(IST),在线程中申请并等待中断:
static DWORD WINAPI MyInterruptThread(LPVOID p) { DWORD RetVal = 0; HANDLE hEvent; DWORD SysintrValue; DWORD IRQ = MYDRIVER_IRQ; /* Create an Event */ hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); /* Register with the Kernel */ KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(DWORD), &SysintrValue, sizeof(DWORD), NULL); RetVal = InterruptInitialize(SysintrValue, hEvent, NULL, 0); /* Set the Thread Priority */ CeSetThreadPriority(GetCurrentThread(), 150); while(1) { /* Wait for the Event to be Signaled */ RetVal = WaitForSingleObject(hEvent, 2000); if(RetVal == WAIT_OBJECT_0) { /* * Service the Interrupt * In this case suspend the device */ SetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE); /* Tell the Kernel that the Interrupt has been Serviced */ InterruptDone(SysintrValue); } else if(RetVal == WAIT_TIMEOUT) { /* * Optional, provide a way to stop the thread when the driver unloads * This is optional because the driver may never unload */ if(StopThreads) break; } } /* When and if the driver unloads and the thread exits release resources */ InterruptDisable(SysintrValue); CloseHandle(hEvent); KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &SysintrValue, sizeof(DWORD), NULL, 0, NULL); return 0; }
驱动Dll被加载后,系统首先调用DllEntry,随后调用XXX_Init。修改XXX_Init,加入线程启动代码:
HANDLE hthrd; // Start thread hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MyInterruptThread,NULL,0,NULL); // Since we don't need the handle, close it now. CloseHandle(hthrd);
如果驱动只需要处理一个中断,WaitForSingleObject可以处理得很好,如果有多个中断需要处理时,能依葫芦画瓢,创建多个event,每个event注册一个中断,然后使用WaitForMultipleObjects吗?很遗憾,虽然WinCE支持WaitForMultipleObjects,但对于注册到中断的event,只允许等待一个,考虑到中断处理程序所要求的高性能,为了避免进入死锁,当event数目大于1时,WaitForMultipleObjects将会失败,GetLastError返回参数无效的错误代码(是的,如果只有一个event,WaitForMultipleObjects仍然会成功)。
在这种情况下,一种解决方法是,创建多个IST,每个IST处理一个中断。
此外,还有另一种更好的方法,就是把同一个event注册到多个中断,然后使用WaitForSingleObject等待此event,每个中断被触发时,event都会获得信号:
int i; HANDLE hEvent; // Create an Event hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // Init all interrupt to a event for(i=0; i<MY_INT_COUNT; i++) { // Register with the Kernel KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irqs[i], sizeof(DWORD), &intrs[i], sizeof(DWORD), NULL) ; InterruptInitialize( intrs[i], hEvent, NULL, 0 ); } . . . . // When and if the driver unloads and the thread exits release resources for(i=0;i<MY_INT_COUNT;i++) { InterruptDisable( intrs[i]); KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &intrs[i], sizeof(DWORD), NULL, 0, NULL); } CloseHandle( hEvent );
(参考了Bruce Eitman的文章,http://geekswithblogs.net/BruceEitman/Default.aspx)
相关文章推荐
- 如何开发一个WinCE 6的流设备驱动
- Windows Embedded 开发之如何创建一个设备驱动(一般性描述)
- WinCE和Win2000/XP设备驱动开发的区别
- VS2005下如何新建一个WINCE设备的DLL工程
- linux驱动开发--一个驱动管理多个设备
- WinCE驱动开发 - 如何旋转wince的桌面
- 如何找到一个usb设备的具体驱动
- linux驱动开发之一个真正的设备驱动需要一些什么元素(设备号,操作方法)
- 开发wince下的usb音频设备驱动总结
- WinCE中如何删除一个驱动(原创小经验)
- 如何在wince下实现一个文件系统驱动
- linux设备驱动第三篇:如何写一个简单的字符设备驱动?
- PlatformBuilder 文档中关于“如何开发设备驱动”的翻译
- WINCE开发更安全可靠设备驱动的最佳实践
- 教教大家如何使用php程序开发一个自动识别移动设备
- linux设备驱动——一个驱动如何管理多个设备
- 嵌入式开发第61日(linux内核模块之设备驱动:怎么写一个简单的驱动)
- 如何在wince下实现一个文件系统驱动
- 如何学习wince驱动开发--转载(作者:gooogle man)
- WINCE开发更安全可靠设备驱动的最佳实践