您的位置:首页 > 其它

USB设备主要函数介绍

2009-07-22 11:06 441 查看
USBInstallDriver:

这个函数在驱动程序DLL被加载的时候会被调用,但是不是任何情况下加载驱动都会调用这个函数入口。

什么情况下调用呢?

当系统能够根据注册表定位到驱动程序dll并且成功加载的话,这个函数就不会被调用了。反之,当不能够找到匹配的驱动或者不能够成功加载驱动的时候,系统会弹出一个对话框,让用户输入一个驱动程序名称,这个时候,系统就会加载用户输入的这个驱动程序文件,并调用其中的 USBInstallDriver函数了。

USBInstallDriver函数里面作什么的呢?说白了,就是写注册表,让系统下次能够通过注册表信息匹配到这个驱动程序文件。

怎么写注册表,就是用USBD.dll中的RegisterClientDriverID和RegisterClientSettings两个函数。

到处都说USBInstallDriver里面不要用Reg的API函数去操作注册表,却没有个所以然,这个应该是因为这些注册表主键可能会根据操作系统的变更而变更的,而不论你是哪个操作系统,RegisterClientDriverID和RegisterClientSettings都会找到对应的正确的注册表主键去添加值,所以建议不要用regAPI来操作,换句话说你用了RegAPI去操作注册表,写入信息,也不会有什么问题,

在USBInstallDriver函数调用完之后,驱动程序dll会被释放掉,然后系统再读取注册表信息去找匹配的驱动来加载,所以才会出现上述情况。因此如果你写入的USB_DRIVER_SETTINGS是和你的设备匹配的,系统就会加载你的驱动,去继续干活了。

这次系统加载会干什么呢?会调用驱动DLL中的USBDeviceAttach入口函数。

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来作为驱动程序,但是显然,你必须实现系统所要求的接口函数。
,lpInterface,一个指向USB_INTERFACE的指针,我一直对这个参数没太弄明白,我在这个函数里面得到的这个指针是一个空指针,而看别人的代码中间,当这个指针为空的时候attach是返回FALSE的,显然对我这种情况是不适用的,我后来想想,觉得大概是因为我的外设 Interface的class、subclass、protocol都是0,所以才出现这种情况吧(准确的说是因为我在USBInstallDriver函数中,RegisterClientDriverID调用给的参数 USB_DRIVER_SETTINGS结构体中关于Interface的几个变量值我全给的USB_NO_INFO,我后来尝试赋值为0,结果就得到了非空的Interface指针)。那么对于我这种情况,interface是个空指针该怎么办呢?可以用USB_FUNCS中的lpFindInterface来“找出”合适的Interface指针,具体的用法还是看官自己研究MSDN吧。

XXX_Init():

这个函数并不是由应用程序直接调用的,而是通过设备管理器提供的ActiveDeviceEx()函数来调用的。由于在设备管理器初始化设备的时候我们已经使用ActivateDevice()函数将设备句柄等信息写入Drivers/Active下面,所以在应用程序初始化时我们只需要将注册表的地址作为Context参数传给XXX_Init(),然后利用RegOpenKeyEx()、RegQueryValueEx()等函数执行打开和读写注册表操作,执行成功后则返回USB设备的句柄等信息。

 在对设备进行读操作之前,首先要先通过执行CreatFile()函数来调用XXX_Open()打开设备,XXX_Open()所需的第一个参数是应用程序初始化时由XXX_Init()返回的设备句柄。而XXX_Read()需要的第一个参数是CreatFile()执行成功后返回的驱动引用实例句柄,第二个和第三个参数分别是用于从驱动中读数据的缓冲区地址和长度。应用程序通过ReadFile()函数来调用XXX_Read(),而在XXX_Read()中通过调用USBD模块提供的不同的传输函数来与不同的USB外围设备进行通信,例如在打印机设备中需要批量传输函数IssueBulkTransfer()。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: