基于WDF的USB驱动程序设计_第1页
基于WDF的USB驱动程序设计_第2页
基于WDF的USB驱动程序设计_第3页
基于WDF的USB驱动程序设计_第4页
基于WDF的USB驱动程序设计_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、基于 wdf 的 usb 驱动程序设计宋爱美,徐建建( 山东科技大学 信息科学与工程学院,山东 青岛 266510)摘要: wdf 是微软推出的下一代驱动程序开发模型,它所提供的 kmdf 框架为内核模式驱动开发提供了一个面向对象和事件驱动的开发框架,对它的研究是设计高效稳定驱动程序的基础。文中首先对基于 wdf 驱动程序开发技术进行了深入分 析,重点讨论了 wdf 模型及其特点,在此基础上,给出了基于 wdf 的 usb 驱动程序设计方法。关 键 词:中图分类号:wdf 驱动程序开发技术; kmdf 框架; usb 驱动文献标志码: bdoi: 10 3969 / j issn 1672 4

2、550 2012 01 019tp311. 1a method of usb driver program design based on wdfsong ai-mei,xu jian-jian( college of information science and engineering,shandong university of science and technology,qingdao 266510,china)abstract: wdf is the next generation driver development model proposed by microsoft it

3、contains kmdf framework which providesan object-oriented and event-driven development framework for kernel-mode driver development the study on it is the base to design highly efficient and stable driver program this paper first analyses the driver development technology based on wdf,focused on the

4、wdf model and its characteristics,then,a design method of usb driver based on wdf is givenkey words: wdf; kmdf framework; usb driverwdf( windows driver foundation,wdf ) 是微软推出的新一代驱动程序开发模型,它支持面向对 象和事件驱动的开发,提供了比 wdm 更高层次抽 象的高度灵活,可扩展的驱动程序框架1。wdf 框架管理了大多数与操作系统相关的交互,实现了 公共的驱动程序功能,隔离了设备驱动程序与操作 系统内核,降低了驱动程序

5、对内核的影响,该框架之间的关系。在 wdm 模型中,驱动程序一方面处理硬件的行为,另一方面又要处理与操作系统内核 之间的交互。它通过引入框架的概念,将驱动程序 和操作系统内核进行了分离。驱动程序通过框架内 定义的对象及方法来实现自己的功能,具体与操作 系统内核之间的通信则由框架去完成。wdf 驱动 模型的具体框架结构如图 1 所示。kmdf ( kernel-modedriver framework, km-driver framework, um-分 为df)和 umdf ( user-modedf) 两种模式。使用 wdf 模型来开发 usb 驱动程序,为操作系统与 usb 设备提供了一种

6、智能机制, 使开发人员无需关注操作系统,只需关注 usb 硬 件设备本身即可。并且使用 wdf 可在不牺牲 usb 驱动性能的前提下,提高其质量,大规模减少其代 码量,大大提高了 usb 驱动程序的可维护性。基于 wdf 驱动程序开发技术分析wdf 驱动模型wdf 通过应用普通程序设计中的基于对象技11. 1图 1 wdf 驱动模型架构1. 2 wdf 内核模式驱动开发框架kmdf1. 2. 1 kmdf 的对象模型作为 wdf 的内核模式驱动开发模型 kmdf 驱 动框架为内核模式的驱动开发提供了一个面向对象 和事件驱动的模型,它定义了一系列的对象来表示 设备、驱动以及队列等信息,每个对象都

7、拥有相应术,为设计者提供了一个面向对象和事件驱动的驱动程序开发架构,改变了驱动程序与操作系统内核收稿日期:基金项目: 作者简介:2011 10 17山东科技大学“群星计划”项目( qx102047) 。 宋爱美( 1963 ) ,女,硕士,实验师,主要从 事嵌入式系统研究与开发。的属性、方法和事件。驱动程序可以利用这些方法设置属性、创建对象和响应事件。kmdf 对象以透 明方式提供方法、对象、事件回调。 本质上基于 kmdf 的驱动只是一个入口( driverentry) ,多个回调函数的集合。基于 kmdf 的驱动从不直接操作kmdf 对象,而是通过 handle 引用对象,把驱动 作为参数

8、传给对象的方法,kmdf 作为参数传给事 件回调函数。kmdf 对象间的关系如图 2 所示。图 2 kmdf 对象之间的父子关系图 2 中框架定义的主要 对 象 有:列,每个输入输出队列的配置结构都定义有不同类型的 i / o 请求接口。kmdf 驱动程序可以通过这些 接口定义自己的 i / o 请求回调例程。当相应的 i / o 请求到达时,kmdf 框架会自动响应该事件,从驱 动程序中调用相应的回调例程进行处理。kmdf 建立自己的分发例程来截获发送给驱动 的 irp 包,图 3 给出了通过 kmdf 和驱动的所有 io 信息流。当 irp 到达,kmdf 指定下一组件之 一进行处理2,i

9、 / o 请求处理,处理请求和设备kmdf( 1) wdfdriver对象。描述一个驱动的实例,包含驱动的一些信息,包括加载的位置,有关的属性 和管理的设备等,每个驱动仅有一个 wdfdriver 对象。( 2) wdfdevice 对象。描述由驱动程序管 理的单个设备实例。设备可以是命名的或者是非命 名的,用户模式的应用程序可以通过定义的设备接 口或者符号名称访问设备。( 3 ) wdfrequest 对象。代表一个设备的 i / o 请求。( 4 )wdfqueue对象。代表一个特殊请求的 i / o 队列,它定义了一系列的事件处理回调函数,当 i / o 请求进入队列 时,框架将自动调用

10、相应的回调函数处理。io;pnp 处理,处理 pnp 和电源,通知其他模块设备状态改变; wmi 处理,处理 wmi 和系统控制请求。这 3 种组件将会按照以下过程进行处理:( 1)触发驱动的事件;( 2)( 3)kmdf 的 i / o 模型转发 irp 到内部句1. 2. 2kmdf 框架为 i / o 请求的处理定义了一个事件驱动模型。它为每个设备对象都提供了多个 i / o 队柄和 io 目标做进一步处理;基于自己的处理,完成 irp;( 4)基于驱动调用完成 irp,完成 irp。图 3kmdf 的 io 信息流wdf 与 wdm 的区别微软以 wdm 为基础进行了建模和封装,推出

11、了新的驱动程序开发环境 wdf,wdf 比 wdm, 有如下优点:1. 3基于 wdf 的 usb 驱动程序开发usb 编程对象kmdf 开发模型提供了 3 类对象实现 usb 设22. 1( 1)备操作:将原来普通程序设计中基于对象的技术应wdfusbdevice、 wdfusbinterface、用到了驱动开发中。为了实现基于对象的技术,微软精心设计了对象模型并进行了封装,包含属性、方法、事件等对象的特点。wdfusbpipe。wdfusbdevice 用于逻辑 设 备 的编程,其方法为 wdfusbtargetdevicexxx。wdfus- binterface 用 于 usb 接 口

12、 的 编 程,其 方 法 为 wdfusbinterfacexxx。wdfusbpipe 用于 usb 管道 编程,其方法为 wdfusbtargetpipexxx4。( 2)无论内核模式的驱动程序或者用户模式的驱动程序,都采用同一套对象模型构建,采用同一个基础承载。wdf 虽然已经是经过封装和定义的 对象模型,但对内核模式和用户模式对象来说, wdf 又是两者的父对象。相对于内核模式,派生 出的对象称为“kmd 框架”即 kmdf; 相对于用户 模式,派生出的模型称为“umd 框架”即 umdf3。 无论何种模式的框架,其内部封装的方法、执行的 行为其实还是用 wdm 完成的。( 3) 封装

13、了驱动程序中的某些共同行为。大多 数驱动程序中都需要处理即插即用和电源管理问 题,wdm 中处理这些操作需要上千行的代码,而 且难写,考虑不周极易出错,wdf 将即插即用和 电源管理封装进了对象中,成了对象的缺省行为。 即使不写此类代码,也不会出错。( 4) 改变了操作系统内核与驱动程序之间的关 系。wdm 驱动程序中,一方面要处理硬件,另一 方面要处理驱动程序与操作系统内核的交互。现在 wdf 则将驱动程序与操作系统内核之间进行了分 离,驱动程序与操作系统交互工作交给框架内封装 的方法( 函数) 完成,这样驱动开发者只需专注处 理硬件的行为即可。这不仅避免了顾此失彼两面不 周的弊端,也由于双

14、方的分离,对操作系统内的某 些改动,硬件制造商配套驱动程序的开发都有莫大 的好处。wdfusbdevice 对象2. 1. 1wdfusbdevice 对象为端点 0,usb 驱动程序通过默认控制管道控制 usb 设备,完成 usb 设 备列举和各种控制操作。其常用函数如表 1 所示。 表 1 wdfusbdevice 对象的方法序号函数描述1 wdfusbtargetdevicecreate创建 usb 设备对象激活或中止 usb 配置 获取设备描述符2 wdfusbtargetdeviceselectconfig3 wdfusbtargetdevicegetdevicedescriptor

15、4 wdfusbtargetdeviceretrieveconfigdescriptor获取配置描述符5 wdfusbtargetdevicequerystring获取字符串描述符获取 usb 设备信息返回 wdfiotarget 对象 返回 usb 接口数目 返回指定接口号的 usb 接口对象 获取当前 usb 帧号测试 usb 设备是否已经连接 复位 usb 设备端口获取字符串描述符6 wdfusbtargetdeviceretrieveinformation7 wdfusbtargetdevicegetiotarget8 wdfusbtargetdevicegetnuminterface

16、s9 wdfusbtargetdevicegetinterface10 wdfusbtargetdeviceretrievecurrentframenumber11 wdfusbtargetdeviceisconnectedsynchronous12 wdfusbtargetdeviceresetportsynchronous13 wdfusbtargetdeviceformatrequestforstring 14 wdfusbtargetdeviceformatrequestforcontroltransfer 控制传输2. 1. 2wdfusbinterface 对象wdfusbinte

17、rface 对象用于获取 usb 接口和管道的信息,其函数如表 2 所示。表 2wdfusbinterface 对象的方法序号函数描述( 5)两种模式的驱动程( kmdf、umdf) 都使返回指定管道索引号的管道对象和管道信息1 wdfusbinterfacegetconfiguredpipe用同一 环 境 进 行 构 建,这 一 环 境 称 为 wdk,即kmd、umdf 的开发环境为 wdk。wdm 开发的环 境把测 试 套 件 ( test suites ) 集 成 后,ddk 就 成 了 wdk。wdk 是针对微软操作系统系列的驱动器集 成开发系统,它组合了 windows ddk 和

18、 hardware获取接口描述符2 wdfusbinterfacegetdescriptor返回 usb 接口的索引号3 wdfusbinterfacegetinterfacenumber4 wdfusbinterfacegetnumconfiguredpipes返回接口的管道数量5 wdfusbinterfacegetnumendpoints返回指定索引号接口的端点数量6 wdfusbinterfacegetconfiguredsettingindex返回当前配置接口的索引号compatibility test ( hct )kits ( 硬 件 兼 容 性 测 试 工7 wdfusbint

19、erfaceselectsetting选择 usb 接口具) ,同时提供了微软内部用来测试 windows 操作系统稳定性和可靠性的测试套件。( 6) 经过封装并引入基于对象的技术,所开发 的驱动程序在执行效率上并不比 wdm 驱动逊色。获取端点信息8 wdfusbinterfacegetendpointinformation 9 wdfusbinterfacegetnumsettings 返回 usb 接口的可选择数目2. 1. 3 wdfusbpipe 对象wdfusbpipe 对象完成管道的控制、 读写操作。其常用函数如表 3. 3 所示。表 3 wdfusbpipe 对象的方法driv

20、erdeviceadd。deviceadd 函 数 的 主 要 功 能 是:创建框架设备对象,创建框架队列,创建设备对象 的符号链接或设备接口,创建设备接口,设置各种 事件的回调函数。其基本执行步骤为:序号函数描述1 wdfusbtargetpipegetinformation获取 usb 管道信息( 1)初始化 wdfdevice _init。typedef nt-2 wdfusbtargetpipegettype返回 usb 管道传输类型status 函数传入两个参数: 驱动对象 driverobject测试是否输入端点3 wdfusbtargetpipepipeisinendpoint和

21、 wdfdevice _结 构 体。 wdfdevice _init测试是否输出端点4 wdfusbtargetpipepipeisoutendpointinit 涉及了设备配置的这些方面: 电源、pnp、电源策略、文件、i / o 等。wdfdevice _ init 的初 始化要在创建设备对象之前进行,通过各种初始化返回 wdfiotarget 对象5 wdfusbtargetpipegetiotarget6 wdfusbtargetpiperesetsynchronously同步复位管道7 wdfusbtargetpipeabortsynchronously同步放弃管道上未完成的请求8

22、wdfusbtargetpipereadsynchronously同步管道读操作操 作。 如apiwdfdeviceinitsetpnppowerevent-同步管道写操作9 wdfusbtargetpipewritesynchronouslycallbacks 初始化 pnp 的各种回调函数。异步复位管道操作10 wdfusbtargetpipeformatrequestforreset( 2)创建设备对象。设备对象的创建函数为11 wdfusbtargetpipeformatrequestforabort异步放弃管道操作wdfdevicecreate,其调用如下:wdfdevice dev

23、ice;wdfdevicecreate ( deviceinit,device) ;12 wdfusbtargetpipeformatrequestforread异步管道读操作13 wdfusbtargetpipeformatrequestforwrite异步管道写操作attributes,14 wdfusbtargetpipeconfigcontinuousreader管道连续读操作2. 2 基于 wdf 的 usb 驱动程序的构成1 个即插即用的 kmdf 设备驱动程序包括:( 3) 创建设备接口。可以使用 wdfdevicecreat-edeviceinterface 创建 guid 接

24、口,也可以使用 wd- fdevicecreatesymboliclink 创建符号链接。( 1) 1 个入口函数driverentry 函数;( 2 ) 1队 列;个 deviceadd 函 数;( 3 ) 1个 或 多 个i / o( 4)创建队列。wdf 中定义了 5 种队列:wd-( 4) 1 个或多个 i / o 事件回调函数; ( 5 ) 支持的即插即用和电源管理回调函数; ( 6 ) 其他回调例程, 如对象的清除函数、中断处理函数等。2. 2. 1 驱动程序的入口函数 driverentrywindows 操作系统中,驱动程序同普通的 exefioqueuedispatchinv

25、ali、 wdfioqueuedispatchsequen-tial、 wdfioqueuedispatchparallel, wdfioqueuedis-和 wdfioqueuedispatc, 其 中patchmanualwdfio-queuedispatchinvali、 wdfioqueuedispatchmax 保 留以 后 使 用。 wdfioqueuedispatchsequential 串 行 队文 件、 dll 文 件、 com 文 件 一 样, 都 属 于pe列,1 次只能向处理函数提交 1 个 i / o 队列请求,( portable execute,移植的执行体) 文

26、件,都有 1 个入口函数。exe 文件的入口函数为 main( ) 或 win- main( ) ,驱动程序的入口函数为 driverentry ( ) , 入口函数的加载由 system 进程完成5。system 进 程首先在驱动文件的 pe 结构中寻找到 driverentry 的函数地址,然后调用它。driverentry 例程中,主要创建并初始化驱动对 象和设置 evtdriverdeviceadd 例程地址。evtdriver- deviceadd 例程地址由配置结构初始化函数 wdf_ driver_ config _ init 设置。wdf 框架已经完 成了驱动对象初始化的很多操

27、作,用户只需在默认 初始化的基础上,增加自定义的初始化操作。如果 没有,wdf 的默认初始化也能保证驱动程序的正 常稳定运行。调用 wdfrequestcomplete 完成当前请求后才能处理下 一 个 请 求。 wdfioqueuedispatchparallel 并 行 队列,一旦有 i / o 请求,就将请求发送给处理函数。wdfioqueuedispatchmanual 手动队列,驱动通过调用 wdfioqueueretrievenextrequest 来手动获取队列 中的 io 请求。我们在系统中创建了 2 个队列: ( 1 ) 串行队 列,用于处理应用程序发来的各种命令; ( 2

28、) 手动 队列,用于处理遥控器按键信息。wdf_ io_ queue_ config ioqueueconfig;/ / 初始化默认队列配置,设置 i / o 请求分发处 理方式为串行wdf _ io _ queue _ config _ init _ de- fault _ queue ( ioqueueconfig,wdfioqueuedis- patchsequential) ;/ / 设置 evtiodevicecontrol 例 程,处 理 应 用 程 序的 deviceiocontrol( ) 函数调用驱动程序的 deviceadd 函数2. 2. 2驱动程序初始化后,pnp 管理

29、器调用驱动程序的 evtdriverdeviceadd 函数初始化该驱动程序所控 制的设备6。usb 设备列举时,系统将调用 evt-获取字符串描述符时,一般执行 2 次 wdfus-btargetdevicequerystring,第 1 次取得描述符实际 长度,第 2 次正式取得字符串描述符。函数调用如 下:status = wdfusbtargetdevicequerystring ( pcon- text- usbdevice, null, null, ( pushort ) pbufferoutput,ioqueueconfig. evtiodevicecontrol= device

30、io-controlserial;/ / 创建 队 列,设 置 环 境 变 量 的 iocontrolseri- alqueuewdfioqueuecreate ( device, ioqueueconfig,wdf_ no_ object_ attributes,pcontext- iocontrolserialqueue) ;2. 2. 3 命令的处理驱动程序在异步队列中收到应用程序发来的指 令,在回调函数 deviceiocontrolserial 中具体处理, 然后通过管道与硬件设备的端点进行通信。向 usbnumcharacters,3,0 ) ;存放版本信息/ / 第 3 个 字

31、符 串,if( nt_ success( status) ) ( ( pushort ) pbufferoutput) numcharacters= l/0;/ / 手动在字符串末尾添加 null设备发送控制命令,需要先初始化 wdf _usb _* poutputbufferlength = numcharacters + 1; 自定义命令的发送主要步骤如下:control_ setup_packet 结构体。wdf 定义了一些宏专门用来对结构体进行初始化。主要有群组命令初始化宏:wdf _ usb _ control( 1)定义控制命令封包_ setup_ packet_ init_ cl

32、ass用户自定义命令初始化宏:wdf_ usb _ control_ setup_ packet_ init_ vendorwdf _ usb _ control _ setup _ packetcontrolpacket;( 2)构造内存描述符ntstatus = wdfmemorycreatepreallocated ( wdf_ no_ object_ attributes,pchget,sizeof( uchar) ,hmem) ;标准命令初始化宏:_ setup_ packet_ initget status 命令初始化宏:wdf _ usb _ controlwdf _ usb _

33、 con-( 3)初始化控制命令trol_ setup_ packet_ init_ get_ statuswdf_ usb _ control_ setup_ packet_init_ vendor(controlpacket,bmrequesthosttodevice,/ / 方向,从主机到设 备bmrequesttodevice,/ / 接收方,是设备0xa2,/ / vendor 命令0,/ / 指定地址0) ;feature 命 令 初 始 化 宏:wdf _ usb _ con-trol_ setup_ packet_ init_ feature表 4 列出了系统中的自定义命令。其

34、中 get_ firmwarever 的数据由固件写在字符串描述符中, 在此就转化为标准命令获取字符串描述符。表 4 系统自定义命令请求代码符号名描述读取当前按键获取遥控器接收端固件版本 获取遥控器版本0xa00xa10xa2get_ keyget_ firmwareverget_ drcver( 4)创建 wdf request 对象。ntstatus = wdfrequestcreate ( null, null,系统中定义的回调函数 deviceiocontrolserial 的声明如下:newrequest) ;( 5) 控制传输方式,将请求发到 usb 总线wdfusbtargetd

35、eviceforma-typedef void ( * pfn _io_ device_ control) (in wdfqueue queue,in wdfrequest request,in size_ t outputbufferlength, in size_ t inputbufferlength, in ulong iocontrolcode) ;wdf _io _queue _trequestforcontroltransfer ( pcontext- usbdevice,newrequest,controlpacket,hmem,null) ;轮询操作操作系统每隔一定的时间(

36、在端点描述符中规2. 3定) 就会轮询一次端点 1,以接收遥控器按键信息。wdf 框 架 中,实 现 设 备 轮 询,可 以 使 用 连 续 读( continuous reader) 操作完成。把读操作划分成了4 个独立进行的任务: 初始化连续读,开启读,读数据处理,结束读。复杂的 irp 的循环分发,以及 在 wdm 实现时要做的其他处理工作,都由 wdf 框架代为操作了。) ;第 1 个参数是为端口句柄,可用来区分多个连续读操作。第 2 个参数为保存读数据的内存句柄。第 3 个参数为读缓冲的长度。这个长度一定是一个小于或等于上面所定义的 transferlength 的值。我 们的功能驱

37、动从总线驱动那里接收读数据。trans- ferlength 是最大可以接收到 的 数 据 长 度,num- bytestransferred 是实际接收到的长度,所以 num- bytestransferred 只可能比 transferlength 小。数据处理的工作,首先是从 buffer 内存句柄中 获取内存缓冲指针,通过调用 wdfmemorygetbuffer 来从内存句柄中获取缓冲区指针。然后分析获得的 缓冲内容并做具体处理。初始化连续读初始化连续读操作,需要设置 wdf _2. 4usb _continuous_ reader _ config 结构体。框架提供wdf _ usb _ continuous _ reader _config _init 宏用来初始化 wdf _usb _ con-tinuous_ readerconfig 结构。 这个宏设置 wdf _usb _config 结构 的 trans-continuous _ reader _ferlength、 evtusbtargetpipereadcomplete、 evtus-btargetpipereadcompletecontext3 个值。实现代码如 下:wd

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论