基于WDM的专用USB设备的驱动程序开发[通俗易懂]

基于WDM的专用USB设备的驱动程序开发[通俗易懂]1引言目前对于诸如USB鼠标、键盘等这样的计算机标准外设,Windows系统已经提供了标准的驱动程序,用户无需再进行任何开发工作。而开发专用USB设备,需要开发专用的驱动程序。Windows2000/XP操作系统不允许用户程序直接访问硬件设备。为了实现对硬件设备的访问和控制,必须通过操作系统所认可的驱动程序对硬件设备实现间接访问和控制。驱动程序通常被认为是操作系统的组成部分,所以,开发驱动程序有严

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

1引言
目前对于诸如USB鼠标、键盘等这样的计算机标准外设,Windows系统已经提供了标准的驱动程序,用户无需再进行任何开发工作。而开发专用USB设备,需要开发专用的驱动程序。
Windows2000/XP
操作系统不允许用户程序直接访问硬件设备。为了实现对硬件设备的访问和控制,必须通过操作系统所认可的驱动程序对硬件设备实现间接访问和控制。驱动程序通常被认为是操作系统的组成部分,所以,开发驱动程序有严格的规范,被认为是计算机高手的工作。而利用DDK进行基于WDMWin32 Driver Model)驱动程序开发,使驱动程序的开发变成了一项比较简单的工作。
2 Win32
驱动程序模型
USB
设备驱动程序必须符合由MicrosoftWindows 98及其后版本所定义的Win32驱动程序模型(Win32 Driver ModelWDM)规格。这些驱动程序称为WDM驱动程序,扩展名为.sys
WDM
定义了一个基本模型,处理所有类型的数据。例如,USB类驱动程序为所有USB 设备提供了一个抽象的模型,并具有由所有客户驱动程序使用的定义好的接口。有了对所有设备类型共同的核心驱动程序模型,使驱动程序开发人员更容易从一种类型的设备移动到另外一种类型的设备上去。而且它也意味着驱动程序模型的内核实现尽可能是固定的。
USB
是使用标准Windows系统USB类驱动程序访问USBDIWindows USB驱动程序接口)的USB设备驱动程序。USBD.sys就是Windows系统中的USB类驱动程序,它使用UHCD.sys来访问通用的主控制器接口设备,或者使用OpenHCI.sys访问开放式主控制器接口设备。USBHUB.sys是根集线器和外部集线器的USB驱动程序。在PCI枚举器发现了USB主控制器之后,它会自动装入相关的驱动程序。
3 Windows USB
驱动程序接口
大多数客户化的USB设备需要由用户来编写设备驱动程序,以响应内核态或用户应用程序的请求。在内核级,命令由客户驱动程序使用内部IOCTL发送给USB系统,例如IOCTL-INTERNAL-USB-SUBMIT-URB允许发出USB请求块(URB)给系统USB驱动程序。URB允许发出几个功能调用给USB系统。用户态USB实用程序也可以发出几个普通IOCTLUSB设备,目的仅仅是得到连接设备的信息。
3.1
函数驱动程序
函数驱动程序(function driver)让应用程序与USB设备,通过API函数来沟通。这些API函数属于WindowsWin32子系统,Win32子系统同时也管理着执行应用程序。函数驱动程序与较低级的总线驱动程序沟通,总线驱动程序控制着硬件。
1是应用程序与各个驱动程序,如何一起完成USB通信的结构图。当设备或子类别的要求超过类别驱动程序的能力时,会有辅助的过滤器驱动程序来类别驱动程序的能力。一个上层的过滤驱动程序位于类别驱动程序的上方。这样,从客户应用程序传来的要求,会先经过上层的过滤驱动程序,然后才传给类别函数驱动程序。一个下层的过滤驱动程序位于类别驱动程序和总线驱动程序之间,如图1。类别驱动程序会将要求传给下层的过滤驱动程序,然后再传给总线驱动程序。
 
图1应用程序与驱动程序完成USB通信的结构
通用串行总线驱动程序(USBD.SYS)是USB系统中负责管理通用串行总线的工作,位于主机上的一个软件。USBD负责控制所有的USB协议操作和高层的中断处理控制。在Windows98及以上版本中,Microsoft定义了一个新的设备驱动程序模型,称之为Windows设备驱动程序模型(WindowsDriver ModelWDM)。
USB
客户应用程序也是一种设备驱动程序,通过定义的一个称之为USB接口的层间接口来访问其下方的USB软件。应用程序正是通过这些USB客户软件来实现与USB设备之间的通信。
针对USB客户应用程序的开发,相应版本的Windows操作系统的设备驱动程序开发包(Device Driver Developer’s Kit,DDK)给出了相应的USB接口函数。并提供了对于这些函数具体使用的参考文档。
3.2
 USBDIIOCTL
为了编写USB设备驱动程序,通常还要在源代码中包含DDK所提供的几个头文件。这些头文件在Windows98下存放在/98DDK/inc/win98目录中,在Windows 2000下存放在/NTDDK/inc/win2000目录中。这些头文件的用途可以总结如下:

usb100.h 
定义了在USB设备驱动程序设计中所要用到的各种常量和数据结构。
Usbdi.h   USBDI
例程,其中包括对USBDUSB设备驱动程序通用的数据结构,适用于内核和用户模式。
Usbdlib.h  URB
构造和各种例程,定义了USBD所输出的服务,适用于内核和用户模式。
Usbioctl.h 
给出了对IOCTL的定义,其中包括对USBDUSB设备驱动程序通用的数据结构,适用于内核和用户模式。
USB
类驱动程序主要通过USB驱动程序接口(USBDI)的内部IOCTL使用。因为它们都是内部IOCTL,所以只能用于内核的调用但却不能用于用户态的应用程序。DDK usbioctl.h头文件源代码说明了如何定义和使用这些IOCTL,这些内部IOCTL实际上是利用Windows系统提供的ICO-CODE宏而由驱动程序开发人员新定义的I/O控制代码。
4
 USB设备驱动程序的实现
4.1
驱动程序的开发环境
Microsoft
公司提供的驱动程序开发包(DDK)提供了许多工具、函数及实例,还有详细的开发文档,使用起来比较方便,尤其在Win32驱动程序模型(WDM)出现以后,使用DDK开发驱动程序变得更加简化。本文就是在Windows 2000下使用DDK来进行相应驱动程序的开发。并且使用Visual C++作为编程工具。
4.2
驱动程序的组成及各部分主要功能
一个WDM设备驱动程序通常可以完成下面这些工作:初始化;创建、删除设备;即插即用处理;访问硬件;处理电源管理;使用WMI处理Win32 I/O及控制请求等等。除WMI外,本文涉及到了以上的所有其它设备,并将这些功能划分为不同设备,借助Visual C++予以实现。表1列出了开发的驱动程序主要功能。其中,初始化设备“Init.cpp”是必不可少的。它包含有一个驱动程序的初始化入口点:具有标准函数原型的DriverEntry例程。当驱动程序被装入时,内核调用这个例程。DriverEntry例程的主要工作是在传递的驱动程序对象(DriverObject)中存储一系列回调例程的指针,以便于在分发例程中调用对应的例程来处理IRP。在即插即用管理设备“PnP.cpp” 中有一个AddDevice 例程,它是PnP管理器在用户插入新设备时调用来创建WDM设备对象的例程。

 

4.3 驱动程序的设计
一般来讲,软件下载可以通过用户层应用程序来进行,也可以由驱动程序来完成。对于没有采用外部ROM硬件设计,设备的固件需要由USB芯片中的内部RAM来存储,软件采用由驱动程序下载的方式。这样一来,驱动程序不但要提供主机与设备间的通信功能,而且要具有软件下载的功能。因此,每个设备需要两个驱动程序文件和一个INF文件。可将多个设备硬件描述信息放在一个INF文件中;多个设备使用同一个通用驱动程序;固件下载驱动程序随设备不同而异。
固件下载驱动程序只具有下载固件的功能,设备与主机间的通信功能由通用驱动程序来完成。当设备插入主机时,由设备上EEPROM中存储的相关设备标识按照INF文件中的指令,首先安装固件下载驱动程序,将固件下载至EZ-USB芯片的内部RAM。然后通过重新枚举,由固件中包含的设备标识按照INF文件中的指令安装通用驱动程序。这样就完成了整个驱动程序的安装,主机即可对设备进行读写,实现与USB设备的通信。
驱动程序文件应安装在操作系统指定指定文件夹。在Windows 2000操作系统下,固件下载驱动程序和通用驱动程序安装在/WINNT/system32/drivers文件夹,INF文件安装在/WINNT/inf文件夹;在Windows 98/me/XP操作系统下, 固件下载驱动程序和通用驱动程序安装在/Windows/system32/drivers文件夹,INF文件安装在/ Windows /inf文件夹。
5
 USB驱动程序装载
5.1
 INF文件
INF
文件是一个文本文件,它含有安装一个设备驱动程序需要的所有必需的信息,包括要复制的文件列表、要创建的注册表项等,用以告诉Windows使用哪一个驱动程序。即一旦Windows检测到一个新的USB设备时,设备管理器会将所有的系统 INF文件,与从设备读取的描述符信息相比较,然后决定加载哪一个驱动程序。在Windows 98Windows 2000上均有相应的快速检测机制,用于加速检测。
INF
文件由若干区段(section)组成,用于帮助Windows识别设备,寻找合适的驱动程序,以及将设备信息储存在系统的注册表内。下面列出几个区段及其功用:
 Version
区段:是l INF文件的表头;
 ClassInstall
区段:安装注册表内的Class区段的一个新类别;l
 Manufacture
区段:用来识别设备,并为每一个设备定义一个安装区段;l
 DestinationDirs
区段:定义CopyFileReadFileDelFile项目所使用的文件夹;l
 Strings
区段:定义其他区段内所指定的字符串。l
值得注意的是,EEPROM中包含的产品IDPID)和厂商IDVID)和固件代码程序中所包含的PIDVID分别对应INF文件中的两组ID,由一个INF文件根据这两组ID进行两次枚举,即完成驱动程序的安装。以UM-2002IOUSB通用数字IO设备的.inf为例,两组ID号如下定义:
[Manufacturer]
%Cypress%=Cypress
[Cypress]
%USB/VID_04B4&PID_0366.DeviceDesc%=EZUSBDIGIT.Dev,USB/VID_04B4&PID_0366
%USB/VID_04B4&PID_0306.DeviceDesc%=EZUSBDI.Dev, USB/VID_04B4&PID_0306
第一组为EEPROM中包含的ID号,第二组为固件代码程序中包含的ID号。
5.2
 WDM驱动程序的安装过程
驱动程序是根据INF文件中的指令来进行安装的。首先,Windows使用 Device Interface描述符中的值来选择装入哪个驱动程序。Windows一开始使用描述符的厂商和产品域(idVendoridProduct bcdDevice)形成硬件ID 。如果找不到与硬件ID型号匹配的安装INF文件,Windows 将从 Interface的类型域bInterfaceCIassbInterfaceSubCIass bInterfaceProtocoI形成兼容ID.。然后,Windows会搜索处理这些兼容ID中某一个的安装文件。如果没有找到安装文件,它会提示用户安装新的设备驱动程序。选择的安装文件会指定要装入的设备驱动程序。并在Windows内部的注册表中注册。
插入USB设备后,如果操作系统找到了匹配设备硬件的INF文件,则会自动完成驱动程序的装载。如果没有找到匹配的INF文件,则在系统的提示下通过手工选择安装文件同样可以完成驱动程序的加载,而且,使用后的INF文件会自动复制到Windows下的INF子目录,这样,在下次插入USB设备时,系统无需提示会自动完成安装过程。
6
 驱动程序的开发过程
基于EZ-USB系列芯片的设备驱动程序开发分为如下主要工作。
 
完成设备固件程序编写;l
 
建立下载固件驱动程序;l
 
建立通用设备驱动程序;l
 
编写INF文件l
 
制作打包分发程序。l
下面以Windows 2000操作系统为例,详细介绍采用NTDDKVisual C++ 6.0工具,建立USB设备驱动程序的方法:
6.1
固件代码的设计
6.2
下载固件驱动程序的建立
建立下载固件驱动程序可分以下7步进行:
CYPRESS开发包内的EZLORADER目录下的文件拷贝到自己建立的目录下(如:D:/USBDR/RELDDR)。
C:/CYPRESS/USB/BIN中的HEX2C.EXEC:/NTDDK/BIN中的BUILD.EXE文件拷贝到D:/USBDR/RELDDR目录下。
将自己开发的固件程序的十六位制文件(如PORTC.C)拷贝到D:/USBDR/RELDDR目录下。
D:/USBDR/RELDDR目录的SOURCES文件中的TARGETNAME=EZUSB行改为自己的文件名如:TARGETNAME=“driveroffirm”
Dos操作符下,用HEX2C.EXE将编译好的固件十六位制文件形式,转换为C文件。即:HEX2C PORTC.HEX PORTC.CPORTC.C中的INTEL_HEX_RECODE结构数组代替FIRMWARE.C中的INTEL_HEX_RECODE结构数组。
f
BUILD.EXE编译,即在命令行方式下键入BUILD –c。正常情况下,应在D:/USBDR/RELDDR/lib/j386目录中生成RELDDR.SYS文件。(若不能生成RELDDR.SYS文件,进入C:/NTDDK/BIN目录,在命令行方式下键入SETENV C:/NTDDK回车,此时显示设置环境完成,在返回运行BUILD –c。注:系统必须装VC++5.0以上的版本)
g
将生成的驱动程序文件放到  //SYSTEM32/DRIVER目录中。
6.3
通用驱动程序的建立
建立驱动程序也可象建立下载固件驱动程序一样分为若干步,但是如果没有特殊要求,Cypress公司提供的通用驱动程序可满足大多数应用需要,可以采用改写通用驱动程序名字的方法,将通用驱动程序重命名为自己的固件文件名,或者直接用通用驱动程序。并将该驱动程序文件放到  //SYSTEM32/DRIVER目录中。
6.4
建立INF文件
上面详细介绍了INF文件结构,建立INF文件最好的方法是用实例INF文件改写,即拷贝一个INF实例文件的复本,将这个复本改写为符合自己要求的INF文件。具体操作如下步骤所列。
 
将实例INF文件另存为自己的INF文件,如yunio.infl
 
在自己的INF文件中,规划好两组PIDVID号,前一组为EEPROM中的ID号,后一组ID要与固件程序中的ID一致;l
 
用自己建立的两个驱动程序文件名替代实例INF文件中使用的驱动程序文件名;l
 
[…File.Inf]区段实例INF文件名更换为自己的INF文件名。l
 
在最后的[String]l 区段可以添加开发者的信息和该设备的名称。
7
驱动程序的打包
建立生成了上述驱动程序文件之后,需要将其打包制作安装盘,以便于分发使用。但驱动程序的打包应该包含以下内容:
下载固件驱动程序;
通用驱动程序;
INF
文件。
8
结束语
应用上述的专用USB设备驱动程序的开发方法及步骤,开发了USB通用数据采集器及USB任意波形发生器等设备,通过实践表明应用DDK进行基于WDMWin32 Driver Model)的专用USB设备的驱动程序开发,使驱动程序的开发变成了一项比较简单易行的工作。可以大大提高开发效率、缩短开发周期。使开发者可将主要精力集中于实现设备功能上,而不需要重复一些底层的工作。为USB技术在系统检测、诊断领域提供了一个很好的借鉴。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/179258.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 图像处理——分水岭算法

    图像处理——分水岭算法首先感谢以下两位的博文帮助我的理解:(1)迈克老狼2012  https://www.cnblogs.com/mikewolf2002/p/3304118.html(2)-牧野-       http://blog.csdn.net/dcrmg/article/details/52498440分水岭算法是一种图像区域分割法,在分割的过程中

  • Android浏览器插件开发[通俗易懂]

    Android浏览器插件开发[通俗易懂]最近做android浏览器插件学到一些东西和大家分享:需要了解的有以下几个方面的知识:1.插件是什么2.android浏览器怎样加载插件和创建实例3浏览器插件和脚本语言的交互4插件内部的数据流一浏览器插件介绍:  1.1概述浏览插件本质是一个功能模块,是浏览器功能的一种扩充。其载体是dll或则so文件。它依附浏览器完成某一特定的功能。插件需要实现浏览器规定的一些函数这些函数叫着NPAPI.正是插件实现了这些函数才可以和浏览器交互。同时浏览器也为插件提供一些函数。在android平台下还有一些专有的函数

  • 第二十九课.回声状态网络ESN[通俗易懂]

    第二十九课.回声状态网络ESN[通俗易懂]目录EchoStateNetworkEchoStateNetwork回声状态网络(EchoStateNetwork)又称为库计算,即ReservoirComputing,被视为是一种神经网络的扩展。ReservoirComputing多用于处理时间序列的预测问题,比如下图:给定一个信号序列:u(0),u(1),…,u(Nt−1)\textbf{u}(0),\textbf{u}(1),…,\textbf{u}(N_{t}-1)u(0),u(1),…,u(Nt​−1)给定

  • MySQL窗口函数简介「建议收藏」

    MySQL窗口函数简介「建议收藏」原文地址:https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html#function_last-value译文:12.21.1WindowFunctionDescriptions本节描述非聚合窗口函数,对于查询中的每一行,这些函数使用与该行相关的行执行计算。大多数聚合函数也可以用作窗口函数,…

  • 【图解算法】模板+变式——带你彻底搞懂字典树(Trie树)

    【图解算法】模板+变式——带你彻底搞懂字典树(Trie树) 啥是字典树?【字典树】(TrieTree)是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串)。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。                                                    ——百度·百科so?所以到底什么是字典树? 还好,它还有其他的名字,更能表述出它的实质:前缀树、单词查找树&nbs

  • phpstorm 激活码密钥无效(JetBrains全家桶)

    (phpstorm 激活码密钥无效)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号