这两天时间完全泡在CE的驱动开发中,学习学习,感觉就是资料不好找,难入门难上手,象我这样仅仅只有eVc4的更是没法调试没法跟踪,困难还是挺多的。学习了两天,现在感觉有那么点意思了,记录一下与大家分享。
首先说明一下,我可能仍然是个门外汉,因为以前基本没做过和硬件相关的东西,这方面知识缺乏的要命,现在公司要求做个驱动出来,也只有硬着头皮上了,学习研究了两天,基本掌握了一些有用的信息,所以认为自己入门了,但仅从自己的感觉出发都可以说我只是窥见了冰山之一角,还有很多很多都不懂。上次的帖子里面介绍了一些当时收集到的比较有用的资料,那个PB我也试着下了,下了一两天没多少,公司网太破,那个ftp又不支持断点续传,可害苦了我了,一个个的文件包100多M,一掉线就得重来,最后我干脆放弃了。那个弟兄有的,干脆打个包把代码发给我好了,谢谢了先。
好,怎们切入正题。首先介绍一下我的驱动目标,目的是为了使在pda上运行的应用程序能够通过USB口和我们这个外设通讯,可以发送指令给外设,也要求从外设获取数据,因此我把它定位在流接口上,这就引出第一个概念,流接口,应该说这里所说的流接口是Wince上驱动的一种,象串口啊这样的可以用CreateFile打开的都属于这个范畴。其关键在于1)实现xxx_系列的函数2)注册表中定义Prefix和Dll。其中xxx就是注册表中Prefix的值,比如串口就是“COM”。而注册表中的DLL就是你的驱动程序dll(wince下的驱动就是一个dll),加载驱动的时候,会到你的dll中去找xxx_系列的函数,所以你的dll一定要导出这些函数符号。
XXX_Init
XXX_Deinit
XXX_Open
XXX_Close
XXX_Read
XXX_Write
XXX_Seek
XXX_IOControl
XXX_PowerDown
XXX_PowerUp
经过测试,其中前六个是必须实现且导出的,否则是不能够成功加载的。 好,先介绍了一些关于流接口驱动的相关知识,这部分在网上还是能够找到不少资料的,我就不多说,回到我要开发的驱动上,说到底我这个还首先是个USB设备,
被识别之后才能将它驱动成一个流设备。
说到USB驱动,就要先介绍一下USB驱动加载过程了。当usb设备接到主机(usb host,因此你的pda必须是能够作为usb host使用的)上时,系统就会根据它的信息去从注册表里查找它的驱动相关信息,在HKLM\Drivers\Usb\LoadClients下面会有一些主键Group1_ID\Group2_ID\Group3_ID\DeviceID,而DeviceID下面有一个字符串Dll=DriverFile.dll
注意,其中Group1_ID,Group2_ID,Group3_ID分别表示什么,以及其匹配的优先级别,可以在《WindowsCE 驱动开发指南》一书中USB驱动开发一章去详细研究。
如果找到匹配的注册表信息,系统就会加载DriverFile.dll,否则就会提示用户输入一个驱动名称。
那么加载dll的时候会有些什么动作呢?驱动程序DLL和普通的DLL是否具备不同的入口点呢?
先回答第二个问题,答案是否定的,其入口点和普通的dll没有区别。但是加载的过程就不那么简单了。你可以理解系统已经作了一些事情,使得你可以用一个普通的dll来作为驱动程序,但是显然,你必须实现系统所要求的接口函数。
对于USB驱动程序来说,有这么几个接口函数是必须实现且导出的:
BOOL USBDeviceAttach(USB_HANDLE hDevice,
LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface,
LPCWSTR szUniqueDriverId,
LPBOOL fAcceptControl,
LPCUSB_DRIVER_SETTINGS lpDriverSettings,
DWORD dwUnused);
BOOL USBInstallDriver(LPCWSTR szDriverLibFile);
BOOL USBUnInstallDriver();
建议大家先读一下sdk的include目录下的usbdi.h头文件,这里面定义了很多usb驱动相关的结构、函数接口,包括注释