流接口驱动程序的系统结构图
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
流接口驱动程序的系统结构图
文档分两部分内容:(1)Dll 、应用程序和设置驱动程序的注册键
(2)USB 流接口驱动流程及函数调用
一:Dll 、应用程序和设置注册键
1: Dll 动态链接库
流接口驱动其基本框架是一个dll 动态连接库。
所有的USB 设备驱动程序必须在它们的DLL 库中呈现一定的入口点从而与USBD 模块进行交互,也使得驱动程序能够创建和管理任何可能需要的注册键。
入口点函数有:USBInstallDriver,USBDeviceAttach,USBUnInstallDriver 。
加载驱动的时候,会到你的dll 中去找xxx_系列的函数,所以你的dll 一定要导出表中所示函数符号。
其中XXX 是三个答大写字母,如串口就表示为COM ,这也是注册表中Prefix 的值。 表1: 函数名称
描述 XXX_Init
当设备管理器初始化一个USB 设备的时候调用这个函数 XXX_Deinit
当设备管理器卸载一个USB 驱动程序的时候调用这个函数 XXX_Open
在打开一个USB 设备驱动的时候应用程序通过CreatFile()函数调用这个函数 XXX_Close
在USB 驱动程序关闭的时候应用程序通过CloseHandle()函数调用这个函数 XXX_IOControl
上层的软件通过DeviceIoControl()函数可以调用这个函数 XXX_Read USB 设备驱动程序处于打开状态的时候由应用程序通过ReadFile()函数调用 用户应用程序
内核
文件系统代码 基于Windows CE 的平台
外接USB 设备 设备管理器 流接口驱动程序 USBD 模块 HCD 模块
XXX_Seek 对USB设备的数据指针进行操作,由应用程序通过SetFilePointer()函数调用XXX_Write 在一个USB设备驱动程序处于打开状态时由应用程序通过WriteFile()调用XXX_PowerUp 在系统重新启动前调用这个函数
XXX_PowerDown 在系统挂起前调用这个函数
DLL中必须建立一个.def文件定义需要输出的函数,这些函数能够被其它代码用动态加
载的方法调用。
.def文件格式:
LIBRARY MyDev(这个字符串要和将要生成的动态库的文件名一样)
EXPORTS
XXX_Init
XXX_Deinit
XXX_Open
XXX_Close
XXX_PowerOff
XXX_Power_Down
XXX_IOControl
2:应用程序中的文件API
USB流接口驱动将USB设备抽象成一个文件。用户可以将USB设备作为标准的文件来操
作,只要调用相应的文件操作就可以和驱动程序打交道。
在应用程序里对应的文件API有CreateFile、DeviceIoControl、ReadFile、WriteFile,CloseHandle、SetFilePointer。
在USB流接口入口点函数USBDeviceAttach中,通过 ActivateDevice函数激活一个流
接口,从而使得使应用程序可以和驱动程序交互。在表1中已列出应用程序中的文件API如
何与Dll动态链接库的流接口函数即XXX_系列函数进行调用。
3:设置注册键
注册键主要控制驱动程序的加载方式。USBD通过跟踪注册键来加载正确的驱动程序。
这些注册键被作为 HKEY_LOCAL_MACHINE\Drives\USB\LoadClients键的子键被保存。USBD
的注册键可以通过驱动程序的函数USBDInstallDriver来创建。USBDInstallDriver通过调
用USBD.dll中的RegisterClientSettings函数来间接地创建注册键。
每个驱动程序的子键具有 Group1_ID\Group2_ID\Group3_ID\DriverName的格式。如果
保留的组标识子键名字与USB设备匹配,就可以将每个组标识子键命名为Default来表示应
该加载的USBD模块。否则,组标识子键的名字由供应商、设备类和协议信息通过下划线连
接而成。
以下代码说明了如何在驱动程序中设置注册键:
(HKEY_LOCAL_MACHINE\Drives\USB\LoadClients)
(Default)
(Default)
(4_1_2)
(String_Driver)
“DLL”=“StringDriver.dll”
以上代码加载的是名称为String_Driver的驱动程序。注册表中的DLL就是的驱动程序dll。
二:USB流接口驱动流程及函数调用
设备插入后,系统在取得 USB设备信息后将自动在注册表中寻找是否有这一项,找到驱动程序dll文件后将首先调用 USBInstallDriver函数,该函数使用USBD.dll中的RegisterClientSettings函数和RegisterClientDriverID函数注册设备,并依据USB设备信息设置注册表项, 这样在这个注册项不丢失的时候,下次插入将能够自动找到,如果这个函数的USB设备信息和实际设备不符,将返回失败。
USBInstallDriver函数调用成功之后,驱动程序dll会被释放,然后系统再读取注册表信
息去找匹配的驱动来加载。这时系统再调用USBDeviceAttach函数, 这个函数主要进行3个方面的工作:
(1)USB设备接口配置的枚举和保存, 备后面传输工作使用;
(2)通过 ActivateDevice函数激活一个流接口,使应用程序可以和驱动程序交互;
(3)调用RegisterNotificationRoutine函数注册一个设备状态回调函数USBDeviceNotification。该函数的主要功能是在设备移除时通知驱动程序停止设备, 释放占用的资源。
ActivateDevice函数调用的时候, 依据参数lpszDevKey找到驱动程序文件,在注册表的HKEY_ LOCAL_ MACHINE\Drivers\Active键写入该USB设备句柄, 并且指定一个索引(设备序号),将驱动程序加载到DeviceManager的进程空间,这时DeviceManager将发送一个新设备插入的消息, 将注册表的地址作为Context参数传给XXX_Init,调用该流接口驱动的XXX_Init函数。
设备管理器调用驱动程序中的XXX_Init函数, 并把上一步添加的注册表的地址(即ActivateDevice函数的第一个参数)作为 XXX_Init函数的Context参数传入驱动程序内。
以上工作完成后, 流式接口驱动程序已被成功加载, 驱动加载完成后, 应用程序再用CreatFile打开设备的时候, 将返回驱动程序上下文给用户程序, 这样用户程序和驱动程序就可以进行交互了。