ImageVerifierCode 换一换
格式:DOCX , 页数:77 ,大小:106.08KB ,
资源ID:11216552      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11216552.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(开发文档.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

开发文档.docx

1、开发文档开发文档.txt世上最珍贵的不是永远得不到或已经得到的,而是你已经得到并且随时都有可能失去的东西!爱情是灯,友情是影子。灯灭时,你会发现周围都是影子。朋友,是在最后可以给你力量的人。 本文由张枕书贡献 pdf文档可能在WAP端浏览体验不佳。建议您优先选择TXT,或下载源文件到本机查看。 WDF USB 设备驱动开发教程(1.2 版) WDF USB 设备驱动开发教程 基于 CY001 作者:张佩,ChinaHearing 技术团队 版本:1.1 时间:2010-4-19 文档说明: 作者写作此文档的初衷,是为了配合 CY001 USB 内核驱动开发套件,更好地让使用者入 门并熟悉 US

2、B 驱动开发.但本文档完全可以从开发板中独立出来,因为这里面说讲到的绝 大部分内容都是通用的 USB 技术知识. USB 接口越来越流行并已经发展到 3.0 版本了,他的强势甚至让 1394 不得不折腰.USB 规范以其易用性和廉价性,应用遍及电子产业方方面面. OSR 推广的 OSR FX2 USB 开发板,对于美国人自己来说,可能不算贵(70 美金) ,但依 我的愚见, 乘以汇率后的价格对于中国的程序员来说太贵了. 我们因此而推出了 CY001 USB 内核驱动开发套件,板子+代码+文档,堪称完美的组合. 版权声明: 本文档是作者和团队成员,前后 10 余月时间推敲完成,前后几易其稿.不仅

3、对内容的 准确性斟酌再三,亦对文字,修辞方面,力求润色.不敢奢望完美,但其间辛苦心知肚明. 文档免费向读者开放,技术爱好者可以通过任何途径传播,复印.但若以此文档进行以盈利 为目地的培训,出版,销售等事务,则不被允许,保留追究之权利. 点击进入: 驱网介绍:CY001 介绍讨论帖 订购地址:CY001 淘宝店 联系作者:ChinaHearing 1 WDF USB 设备驱动开发教程(1.2 版) 目录 一. WDF 简介 4 WDF 的特点 4 I/O 与队列 4 兼容性 6 PNP 和电源实现 6 其他 8 二. 1. USB 设备硬件结构 9 主从结构 9 2. 硬件拓扑 10 3. US

4、B 中断 11 三. USB 软件结构 12 总线驱动 12 系统类驱动 13 功能驱动 14 父驱动与混合设备 14 过滤驱动 16 USB 驱动栈,设备栈 16 四. 1. 2. 内核开发 18 设备驱动 18 入口函数 18 3. USB 描述符 20 3.1 描述符介绍 20 3.2 程序读取描述符 25 4. 初始化 27 4.1 设备初始化函数 27 4.2 创建设备对象 30 4.3 设备命名,符号链接 31 5. 启动设备 35 5.1 2 接口配置 36 WDF USB 设备驱动开发教程(1.2 版) 5.2 设备电源能力和策略 38 5.3 辅助操作 43 6. 停止设备/

5、反初始化 45 6.1 7. USB 设备反配置 45 数据 I/O 操作 46 7.1 7.2 7.3 7.4 USB 控制命令 46 构造并发送控制命令 47 读 USB 中断端口 49 连续读操作 50 7.5 数据处理函数 51 7.6 中断端口的效率 52 7.7 8. 读写批量端口 53 设备控制 55 I/O Target 对象 55 1. 2. 3. 4. 4.1 4.2 获取 USB 版本 56 管道重置 59 设备重置(Reset) 60 管道中止与终止 61 中止操作 61 终止操作 62 五, 驱动验证- WDF Verifier 63 六, 1. 2. 4. 用户程序

6、 73 内核读写 73 控制命令 73 注意点 74 3 WDF USB 设备驱动开发教程(1.2 版) 一. WDF 简介 WDF 的特点 微软刚开始设计 WDF 的时候,准备搞一套新的 Miniport 驱动,如果真是这样的话, 那么系统中可能又多了一个 WDF Miniport, 就好象 NDIS Miniport 一样. 但好在不少人提 出反对意见:Miniport 驱动越来越多,驱动越来越难写.有人就以 NDIS 为例,在 NDIS 中想获取并处理 IRP 是一件难事,而很多时候,人们又急切地想获取 IRP 对象,这就成 为一件极其痛苦的事情.另外一件痛苦是,某个微端口被推出后,往往

7、只对较新的系统 给予支持,而旧系统则不支持.以 AVStream 微端口驱动为例,就只支持 XP 及以后的系 统,如果要在 Win 2000 上安装 AVStream 驱动,则非常麻烦.这使得编程人员难以实现 驱动程序的多平台支持. 综合分析了各种微端口的缺点,大家最后得到了几个共识: 新的驱动框架,应该做到 WDM 兼容,使得程序员在编程过程中能很方便地在 WDF-WDM 之间进行切换. 新的驱动框架,应该做到向后兼容.也就是说,WDF 推出于 Vista 系统之后,但它 必须向后支持 Win XP,2000 这些旧的操作系统. I/O 与队列 WDF 的一个主要特点是,所有的东西都被封装成

8、一个对象,而所有的操作都被定 义成一个事件(Event)或回调(Callback). WDF 对每个框架对象都维护一个引用计数, 这样 就能有效地控制对象的生命周期. 举例来说:WDF 的一个优点是将 I/O 进行了封装,使得程序员不用直接面对 IRP, 而只要处理 WDFREQUEST 对象,处理也变得异常简单.而 I/O 的对象不再是设备对象, 而是一个新的 I/O target 对象.I/O target 对象比 DEVICE_OBJECT 更广,它不仅可以代表 设备,也可以代表驱动,队列等.队列对象是一个全新事务,WDM 编程中涉及到队列 的地方不多, WDF 却让他成为了不可避免的部

9、件. 但 队列是专门用来管理 WDFREQUEST 对象的,因为 WDFREQUEST 对象是对 IRP 的封装,所以队列归根到底是对 IRP 的管理. 队列允许 WDFREQUEST 对象以三种方式发送给驱动处理:并行,串行,手动.由于对 IRP 的管理,使用失措,而导致的驱动问题,是 WDM 程序的一大难点.现在队列的引 入,让 IRP 从野马变成了驯良的座骑. 由于队列比较重要,下面我们分别来讲一讲.三者中,并行最好理解了,和 WDM 中的无序方式一样,所有的 IRP 都是并行处理的,也就是说,收到一个 IRP 就立即处理 一个 IRP.串行和手动可能较难理解,下面我们举例演示串行队列的

10、使用. 我们假设有一个用户线程 X 以同步方式向内核发送一个命令.内核框架收到命令 后,判断出命令应当归于串行队列 1.此时串行队列 1 中已经有 3 个排队命令. 下图中,图 1 显示了新命令的入队过程;图 2 显示了命令的处理过程;图 3 显示了 命令完成后的线程,队列状态. 4 WDF USB 设备驱动开发教程(1.2 版) 线程 X (串行队列 当前被处理 3 3 WDF 1 1) Request 1 Request 2 Request 3 / User 内核 2 2 *黄色小球代表一个 Request 1. 用户线向内核驱动发送一个请求,WDF 框架首先获得处理这个请求的机会. 2.

11、 此请求隶属于串行队列,WDF 便将请求排到串行队列的最后面:Request4. 3. 线程将一直等待 Request 4 的完成 图 1 Request 排队 线程 X (串行队列 1) / / / Request4 2 WDF 1 2 被处理 *黄色小球代表一个 Request 1. 队列中的前面三个请求别处理完成,Request4 被处理. 2. Request4 处理结束后,WDF 回向通知用户线程,并返回处理结果. 图 2 完成 Request 线程 X WDF / / / / 1 内核中的串行队列空(或者继续接受新命令) 图 3 新状态 2 线程 X 继续执行 5 WDF USB

12、设备驱动开发教程(1.2 版) 图 3 新状态 每个设备对象都有一个默认队列,未经特殊说明的请求类型都被送往这个默认队列中, 如要把某些请求排列到特殊队列,则需特别说明.一般总是把默认队列设置为并行队列,这 是为了将效率最大化.只将部分需特别处理以保证安全的对象,放置到串行队列中.而手动 队列一般放置一些特殊的请求,这些请求往往是为了等待某个条件被满足以达到同步目的, 或等待需要的数据到来,如从 USB 的中断端口读取数据. 多个队列之间可以互通生气, 就是说, 队列中的请求, A 可以被送到 B 队列中进行排队, 这种交流存在于任何的两种队列之间.在不少情况下,需要用到队列转移,比如说, I

13、RP_MJ_DEVICE_IO_CONTROL类型的请求, 一般都可以被并行处理的, 但控制号为 CTL_CODE 为 IOCTL_REQUEST_1 的 DEVICE_IO_CONTROL 请求却必须被串行处理;这时候我们可以把 IRP_MJ_DEVICE_IO_CONTROL 请求设置为在并行队列中排队,这样绝大部分的控制请求都将 被并行处理,而当并行队列的处理函数遇到控制码为 IOCTL_REQUEST_1 的时候,放弃对它 的处理,并重新将他送到串行队列中排队等待. 兼容性 兼容性体现在两个方面,很令人振奋:对 WDM 的兼容,对旧系统的兼容. 能兼容 WDM, 或者说能轻松切换到 W

14、DM 模式是 WDF 的一大优点. 如果不实现这一点, 将给很多人带来痛苦.特别是当人们使用某个小端口驱动,将代码写了一大半的时候,忽然 发现某个必须用 WDM 才能完成而难以实现的问题时,将导致天大的痛苦. 在 WDF 程序中可以很容易获取 IRPs, device objects, driver objects 这三种对象,并按照 WDM 方式处理它们.实际上,这就够了. 对旧系统的兼容,这一点一直以来,就不是微软的强项.但 WDF 却令人刮目相看.虽 然在它的第一版被发布的时候 Vista 系统已经推出,但他却能够支持所有的 NT 系统,并且 所提供的 WDF 示例代码,能够在所有 NT

15、 平台上跑.这使得我们可以一个驱动同时支持 WIn2000,XP,Vista,Win7 这些系统,而不用在代码中对系统进行判断,更不用每个系统 各写一个驱动版本.其实很多组件达不到这个要求,让我们看看 NDIS,AVStream 的表现吧, 就有理由回过头来赞赏 WDF. PNP 和电源实现 恐怕这才是最令人高兴的! 几乎没有人能写出 PNP/电源处理没有一点问题的驱动代码来.真的,因为实在是太复 杂了,分叉路径太多了.WDF 为 PNP,电源,电源策略三者定义的状态值,据说达到近两 百种之多想要实际领略一下,请在 WDK 文档中搜索查看 WDF_DEVICE_PNP_STATE , WDF_

16、DEVICE_POWER_STATE 和 WDF_DEVICE_POWER_POLICY_STATE,三者加起来超过了270 个枚举量.按照最苛刻的要求,你当然也要在驱动中把这些状态都进行处理,哪怕大部分状 态只有百万分之一的几率发生.恐怕没有人曾经把这么多的状态都自己处理过吧用 WDM 代码! 其他令人头疼的问题还包括: pending I/O, correct I/O handling and synchronization, DMA. 它们都看似容易,却实在很难被处理的,因为其内部实现的复杂性.我不准备在这里对此内 容进行讨论.但值得欣慰的是,WDF 将从此让我们好过起来,当遇到上述这些

17、问题的时候 微笑吧,程序员们!蓝屏会远离我们的,而更强壮的驱动代码在朝我们招手. 6 WDF USB 设备驱动开发教程(1.2 版) WDF 对电源和 PNP 的设计方式是,进行最基本的处理,框架向程序提供回调接口,如 果程序注册了某个回调, 则框架在对应的状态变化时刻调用此回调, 否则就使用默认的处理 方式. 下面是 PNP/Power/Power 策略三者的回调函数结构体定义. / PNP/电源回调 typedef struct _WDF_PNPPOWER_EVENT_CALLBACKS ULONG Size;/ 结构体长度.结构体版本存在升级趋势. / 初始与结束回调函数. / 初始:E

18、vtDeviceD0Entry 早于 EvtDevicePrepareHardware 被调用; / 结束:EvtDeviceD0Exit 晚于 EvtDeviceReleaseHardware 被调用; PFN_WDF_DEVICE_D0_ENTRY EvtDeviceD0Entry; / 进入 D0 电源状态 PFN_WDF_DEVICE_D0_EXIT EvtDeviceD0Exit; / 退出 D0 电源状态 PFN_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware; PFN_WDF_DEVICE_RELEASE_HARDWARE

19、 EvtDeviceReleaseHardware; / 设备被 REMOVE 后,调用此回调来释放在 EvtDeviceSelfManagedIoInit 中 / 为每个框架设备对象申请的资源. PFN_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP EvtDeviceSelfManagedIoCleanup; / 当设备被 REMOVE 后,此回调被调用来处理遗留的 IO REQUEST 对象. PFN_WDF_DEVICE_SELF_MANAGED_IO_FLUSH EvtDeviceSelfManagedIoFlush; / 首次进入 D0 状态后,系统为驱动创建

20、的每个框架设备对象调用此函数,来申请 / 专属于此设备对象的资源. PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT EvtDeviceSelfManagedIoInit; / 上面申请的设备资源将被暂停,三者可能性: / 设备休眠,设备拔除,或者 PNP 管理器试图重新分配系统资源. PFN_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND EvtDeviceSelfManagedIoSuspend; / 资源被暂停后又可以重新使用了.只有当系统从休眠状态醒来时,才会被调用. PFN_WDF_DEVICE_SELF_MANAGED_IO_RESTAR

21、T EvtDeviceSelfManagedIoRestart; / 设备被异常拔除 PFN_WDF_DEVICE_SURPRISE_REMOVAL EvtDeviceSurpriseRemoval; / 查询设备是否能够被移除 PFN_WDF_DEVICE_QUERY_REMOVE EvtDeviceQueryRemove; / 查询设备是否可被停止 PFN_WDF_DEVICE_QUERY_STOP EvtDeviceQueryStop; / 当驱动使用一些特殊文件的时候,此回调被调用. / 特殊文件是这三者:页文件,休眠文件,Dump 文件 PFN_WDF_DEVICE_USAGE_NO

22、TIFICATION EvtDeviceUsageNotification; / 系统初始化的时候,或者驱动属下的多个设备对象之间的关系发生变化时,此回调被调用. PFN_WDF_DEVICE_RELATIONS_QUERY EvtDeviceRelationsQuery; WDF_PNPPOWER_EVENT_CALLBACKS, *PWDF_PNPPOWER_EVENT_CALLBACKS; 以及: / 电源策略回调 / 关于电源策略请看下面章节介绍 typedef struct _WDF_POWER_POLICY_EVENT_CALLBACKS ULONG Size;/ 结构体长度. /

23、 设备将进入休眠状态了,尚未离开 D0 状态. / 实现电源策略:让设备可以从即将进入的睡眠状态中醒来. PFN_WDF_DEVICE_ARM_WAKE_FROM_S0 EvtDeviceArmWakeFromS0; 7 WDF USB 设备驱动开发教程(1.2 版) / 设备从休眠状态中被唤醒,进入 D0 状态. / 实现电源策略:为了让设备进入休眠后不再醒来,要在这里做一些设置 PFN_WDF_DEVICE_DISARM_WAKE_FROM_S0 EvtDeviceDisarmWakeFromS0; / 设备自己把自己从休眠状态中被唤醒,此时已经进入 D0 状态. / 但 EvtDevic

24、eDisarmWakeFromS0 还没有调用. / 实现电源策略:能接受并处理唤醒信号. PFN_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED EvtDeviceWakeFromS0Triggered; / 下面的三个函数类似前三个,但这里的系统状态是 Sx,而前面的系统状态是 S0 下. / 上面的唤醒,仅仅是设备唤醒自己;而这里的唤醒,也包括把系统从 Sx 唤醒到 S0 下. PFN_WDF_DEVICE_ARM_WAKE_FROM_SX EvtDeviceArmWakeFromSx; PFN_WDF_DEVICE_DISARM_WAKE_FROM_SX EvtDe

25、viceDisarmWakeFromSx; PFN_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED EvtDeviceWakeFromSxTriggered; / 是 EvtDeviceArmWakeFromSx 的高级版本,提供了更详细信息.在 WDF 1.7 以后才有. /不应该同时存注册这两个回调函数.他多了两个参数,使得函数能够明白自己被调用的原因. PFN_WDF_DEVICE_ARM_WAKE_FROM_SX_WITH_REASON EvtDeviceArmWakeFromSxWithReason; WDF_POWER_POLICY_EVENT_CALLBACK

26、S, *PWDF_POWER_POLICY_EVENT_CALLBACKS; 所有的回调函数,都在被动级别上运行,这替我们省去了很多麻烦.这使得程序在进行 初始化或反初始化的时候,不用担心运行于分发级别(DISPATCH_LEVEL)而顾忌重重.因为 在分发级别上运行的代码有很多限制,常常免不了要使用 WorkItem,而使用 workitem 往往 又必须同时实现同步,相当麻烦. 上述的回调函数和 WDM 的分发函数间,谈不上一一对应,但也存在着比较强的对应关 系.比如函数 EvtDevicePrepareHardware 对应了 WDM 中的 PNP_START_DEVICE 分 发; 函

27、数 EvtDeviceReleaseHardware 对应了 WDM 中的 PNP_STOP_DEVICE 分发; 函 数 EvtDeviceSurpriseRemoval 对应了 WDM 中的 PNP_SURPRISE_REMOVE 分发; 函 数 EvtDeviceD0Entry/EvtDeviceD0Exit 对应了 WDM 中的 PNP_SET_POWER 分发, 等等. 在处理 PNP_START_DEVICE 的时候, 免不了要担心一下是第几次调用 StartDevice 函数来,考虑电源状态是否已进入 D0 状态.EvtDevicePrepareHardware 回调却不必 有此

28、顾虑,因为框架已在内部做了考虑. 其他 WDF 中包含了两套子框架,即:KMDF 和 UMDF.KMDF 用来编写内核驱动;UMDF 用 来编写用户层驱动.本章中只涉及 KMDF 的内容,所以绝大部分情况下,WDF 仅指 KMDF 而言.WDF 仍在不断的发展中,四五年的时间里,他得到了越来越多人们的推崇,而对于 他的将来,人们还有更多的憧憬.比如希望微软总有一天能够将 WDF 代码开源;比如 WDF 也许有一天会改成用 C+来实现,以实现更多的封装,继承特性.等等. 8 WDF USB 设备驱动开发教程(1.2 版) 二. 1. USB 设备硬件结构 主从结构 首先从硬件角度介绍 USB,本

29、文档的任务在于内核开发,硬件知识只能点到为止. USB 的全称是 Universal Serial BUS(通用串行总线) .硬件上,他有两个显著的特点:串行数据传 输,支持热拔插.从 1996 年 1 月第一个版本发布到今天,USB 已经经历了四个版本:1.0, 1.1,2.0 和 3.0.其应用遍及各个领域,方方面面. USB 的另外一个特点是他采用主从结构.两个可以互联的设备,一定有主从之分.这导 致了两台主机(主设备)或者两台 MP3(从设备)之间,没有办法互联.只能在设备(MP3) 和主机之间建立主从互联关系.当然,后来出现了 OTG,可以让设备更换角色.但并未能改 变主从结构的本质

30、. 能成为 USB 主机,就一定要具备两种设备:USB 主控制器,USB 根集线器.主控制器用 来处理根集线器上的数据,交给系统处理;根集线器用来连接多个外部设备.读者请注意不 能把这里的根集线器和普通 USB 集线器全然划等号,应当把 USB 集线器也理解为 USB 外部 设备的一种,不是主机的组成部分. 主控制器 根集线器 集线器端口 外部设备 图 1 主机和设备 从上图我们了解到,设备-集线器-控制器-系统,就像碗中杯,杯中勺一样,层层套 叠.我们在使用的电脑,每台电脑都有若干个控制器,控制器上有一个或多个根集线器,集 线器上又对外暴露出一个或多个 USB A 型接口让外部设备连接. 将

31、设备管理器的视图模式选 为按连接排序设备后,可看到下图所示的层次结构. 图 2 控制器,集线器和设备 最上层是 USB EHCI 接口的控制器,中间层是控制器上唯一的根集线器,最下层是连接 在根集线器上的设备. 每个 USB 控制器,作为一个 USB 族群之灵魂,其驱动程序负责为子设备分配总线地址. 总线地址为 7 位宽,由于控制器自己占一个地址,故而最多可提供(27 -1 = 127)个子设备 地址, 也就是说, 每个控制器上最多能连接 127 个子设备. 并且, 这个数目包含了根集线器. 电器特性方面,标准 USB 接口有 4 个金属针脚,对应着 USB 线中,就是 4 根金属线: 9 WDF USB 设备驱动开发教程(1.2 版) 两根电源线,两根数据线.两根电源线,一个接 5V 电源,一个接地.两根数据线,实现了 数据的差分传输,提高了稳定性,等于是一根线,也就是串行之由来了. 说到电源线,就说说设备供电.USB 设备可以自己供电,也可以从总线获取电源.总线 获取的电源, 就是通过 5V 电源线传过来的. U 盘, 像 鼠键这类小型设备, 电源或者 100mA 5V 电流足以满足其设备需求,故而多从总线获取电源;移动硬盘,打印机,专业 USB 声卡这 种较大设备,往往需要外置电源,也就是自己供电.巧得很,我发现 XP 系统中的根集线器 驱动程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1