Windows下usb接口驱动技术(二)

系统 1499 0

八、 Windows 驱动程序模型

Windows 环境下驱动程序共有三类,一类是 VxD Virtual Device Driver ,虚拟设备驱动程序),起源于 Windows 3.1 时代,用于 Windows 95/98/Me 操作系统中;一类是 KMD Kernel Mode Driver ,内核模式驱动程序),用于 Windows NT 下;还有一类就是 WDM Win32 Driver Mode Win32 驱动程序模型),是微软从 Windows 98 开始,推出的一个新的驱动类型,它是一个跨平台的驱动程序模型,不仅如此 WDM 驱动程序还可以在不修改源代码的情况下经过重新编译后在非 Intel 平台上运行,毫不夸张地讲, WDM 算得上是 21 世纪的驱动程序框架。

WMD 驱动程序模型

Windows下usb接口驱动技术(二)

应用程序通过 API 函数调用 Win32 系统子函数,驱动程序分为设备驱动程序,总线驱动程序 (USBD) 和主控制器驱动程序 (HCD) 三层,它们均运行在系统的内核模式。设备驱动程序使用 IR P(I ORequest Packet) 通过总线驱动程序提供的软件接口 (USBDI USB Driver Interface) 向总线驱动程序发出 I O 请求,并根据数据传输方向提供一个或空或满的 内存 缓冲区; USBD 负责管理数据的总线传输,也有设备驱动程序与其他软件接口的功能单元进行通信,没有直接调用 USBD ,但总有一个更低层的驱动软件发生 USBD 调用。主控制器驱动程序处在 USB 系统软件的最底层,直接与主控制器的硬件通信,它提供了只有总线驱动程序才能访问的主控制器驱动程序软件接口 H CDI (Host C ON TROL Driver Interface) 。其中,总线驱动程序和主控制器驱动程序是系统的底层驱动程序。设备驱动程序是针对某一 USB 设备的专用驱动程序。

Windows USB 设备提供了底层驱动程序,与底层驱动程序接口的是 I O 请求包 (IRP) Windows 为应用程序提供的接口则是 API 函数。因此必须在它们之间建立一个驱动程序,在底层驱动与 Win32 应用程序之间传递消息,即设备驱动程序。 VC++ VB 等软件开发的应用程序,在设备驱动程序的支持下,都可以调用 ReadFile() WriteFile() DeviceIo CONTROL () API 函数向设备传递主机请求。 Windows 系统自动将 API 调用转化为 IRP ,设备驱动程序把它向下层驱动传递。直到完成其所指定的功能再沿驱动程序栈返回主机。

usb

WDM 还引入了功能设备对象 FDO Functional Device Object )与物理设备对象 PDO Physical Device Object )两个新类来描述硬件,一个 PDO 对应一个真实硬件。一个硬件只允许有一个 PDO ,但却可以拥有多个 FDO ,而在驱动程序中我们不是直接操作硬件而是操作相应的 PDO FDO 。驱动程序和设备对象的分层情况如图所示。

其中总线驱动程序( Bus Driver )位于最底层,控制对总线上所有设备的访问,创建 PDO 代表发现的设备。功能驱动程序( Function Driver )控制设备的主要功能,分层在总线驱动的上面,负责创建 FDO 。在 USB 情况下,功能驱动程序必须使用 USB 类驱动程序访问设备。

九、 USB 设备驱动程序开发工具

开发 USB 设备驱动程序需要专门的开发工具,目前应用广泛的工具主要有两大类。 开发设备驱动程序一般采用以下几种方法: 1) 直接使用 Windows DDK ,这种方法开发难度较大,设计者必须对整个体系结构有很好的理解和把握。 2) 使用 Driver Studio ,该 工具 软件可为设计者提供驱动程序的整体框架,设计者只需要专心于功能代码设计。 3) 使用 win Driver ,这种方法开发驱动程序很容易,但工作效率不是很高。

1. Microsoft 公司提供的 Windows DDK(Device Driver Kit)

它有 Windows 98 DDK Windows 2000 DDK 两个版本。 Windows 98 DDK 能够开发 Windows 95/98/Me/NT 下的 VxD KMD WDM 驱动程序。 Windows 2000 DDK 能够开发 Windows 98/Me/NT/2000 下的 KMD WDM 驱动程序。由于 DDK 基于汇编语言的编程方式和内核模式的调用,对没有深厚的 OS 原理和编程水平的人员来说,任务相当艰巨。

2. NuMega 公司提供的 DriverStudio

它是一个大的开发工具包,包含 VtoolsD SoftICE DriverWorks 等开发工具。 VtoolsD 开发包提供了对 VxD 编程的 C/C++ 类库支持,利用 VtoolsD 中的 QuickVxD 工具可以快速生成 VxD C/C++ 代码框架,开发者可以在此基础上根据各自的需要添加自己的代码。 DriverWorks 用于开发 KMD WDM 驱动程序,并且对 DDK 函数进行了类的封装,从而为开发 Windows NT Windows 2000 Widnwos98 WDM 设备驱动程序提供了一个自动化的方法。

DriverWorks ,提供了 VC++ 下的开发向导 Driver Wizard ,按照它的提示可以迅速地生成驱动程序的框架。这个框架结构提供可以正确执行 WDM 动态环境中 IRP 的请求,而且,也包含用于简化系统提供的标准类驱动程序(如 HID 、流)和总线驱动程序(如 PCI USB )接口的类等。 总之,利用 DriverWorks 开发 WDM 驱动程序,可以大大简化开发人员的工作量、缩短开发周期以及降低开发驱动程序的难度。

十、 USB 设备驱动程序的设计

使用 DriverStudio3.2 开发 USB 设备驱动程序。

该驱动程序的主要功能包括:从控制端点 0 读取规定个数的数据、向端点 0 发出控制命令、从端点 2 批量读数据、向端点 2 批量写数据,驱动程序的开发采用 DriverStudio3.2 驱动程序开发包及 VC++6.0 ,使用开发包中的向导程序 DriverWizard 就可以方便的生成驱动程序框架、模块及部分程序源代码,开发者只需要在功能模块中加入自己的实现程序就能完成复杂的 USB 设备驱动程序设计。

1. DriverWizard 生成一 ISP1581 驱动程序的过程:

(1) 启动 DriverWizard ,选择 DriverWorks Project 创造一个名为 USBDIO VC++ 项目 ;

(2) 在驱动程序类型中选择 WDM Driver WDM Function Driver, 在硬件设备所支持的总线类型中选择 USB(WDM Only) ,在 USB Vendor ID( 厂商识别码 ) 中填写 0741 ,在 USB Product ID( 产品识别码 ) 中填写 0821;

(3) 增加 USB 设备端点,设置端点 2 为批量输入 / 输出传输方式 ;

(4) 在驱动程序支持的功能项中选择 Read Write Device Control Cleanup;

(5) 选择自动产生批量读及批量写程序代码 ;

(6) I/O 请求 IRP 处理方式中选择 None ,即 IRP 不排队 ;

(7) 在接口的打开方式中选择 Symbolic link:UsbdioDevice ,即应用程序以符号链接名打开设备 ;

(8) 定义应用程序调用 DeviceIo Control 函数对 WDM 驱动程序通信的控制命令。

(9) 最后选择完成并确认生成新的项目信息,向导程序就会在 usbdio 目录中生成一个名为 USBDIO 的项目文件,其中包括了 ISP1581 驱动程序框架、模块及部分源代码。

2 USB 设备驱动程序的编程

在使用 DriverWizard 生成驱动程序框架、模块及部分程序源代码后,开发者只需完成三个控制代码所对应的三个功能模块的编程:模块 USBDIO_IOCTL_ ID_CODE_Handler 的功能是从控制端点 0 读取数据,模块 USBDIO_IOCTL_ TEST_COMMAND_Handler 的功能是向控制端点 0 发送一个控制命令,模块 USBDIO_IOCTL_DMA_COMMAND _Handler 的功能是向控制端点 0 发送一个要求 USB 设备进行 DMA 传输的控制命令,下面是第一个模块的编程实例。

NTSTATUS USBDIODevice::USBDIO_IOCTL_ID_CODE_Handler(KIrp I)

{

NTSTATUS status =STATUS_SUCCESS;

t << "Entering USBDIODevice::USBDIO _IOCTL_ID_ CODE_Handler, " << I << EOL;

PURB pUrb;

ULONG numData;

numData=*(PUCHAR)I.IoctlBuffer();

// 设置读取的数据个数

pUrb=m_Lower.BuildVendorRequest((PUCHAR)I.IoctlBuffer(),// 驱动程序存放读取的数据的内存区

numData,//wLength ,读取的数据个数

0,0x0c,//bRequest 0,//wValue

TRUE,//input

TRUE,

NULL,

0x0472,//wIndex, 传输到固件程序的读数命令码

URB_FUNCTION_VENDOR_ENDPOINT,

NULL);

if(pUrb==NULL)

{

I.Information() =0;

status=STATUS_INSUFFICIENT_

RESOURCES;

}

else

{

I.Information() =numData;

tatus=m_Lower.SubmitUrb(pUrb,NULL,NULL,0);

delete pUrb;

}

return status;

}

对象 I 包含了应用程序下传的 IRP 内容,包括命令或数据等参数,函数 BuildVendorRequest 用来分配并初始化一个用于厂商请求的 URB(USB Request Block) ,该 URB 将作为下传 IRP 的一个参数,通过函数 SubmitUrb 发送给总线驱动程序,以便完成与硬件的通信。

在初始化 URB 时需要了解 USB 的传输方式及传输协议,该功能使用了 USB 的控制传输方式,该方式包括三个阶段:设置阶段、数据阶段和状态阶段,其中数据阶段可选,开发者主要关注设置阶段中的 8 个关键字节的定义, 8 字节分成了 5 个字段,定义了传输请求及相关信息。

BmRequestType 1 字节,用来指定数据流动的方向,请求的类型,以及接收者。

bRequest 1 字节,用来指定请求。

wValue 2 字节,主机用来传输信息给设备,开发者可以根据情况自己定义。

wIndex 2 字节,主机用来传输信息给设备,开发者可以根据情况自己定义。

wLength 2 字节,包含数据阶段中接下来要传输的数据字节数目。

十一、 USB 设备驱动程序的安装及调用

1. USB 设备驱动程序的安装

驱动程序编译完成后会生成一个名为 USBDIO.SYS 的文件,即 USB 设备驱动程序,另外在使用向导程序 WizardDriver 生成驱动程序时会产生一个名为 USBDIO.INF 的驱动程序安装程序,对此程序只需稍做修改就能正常使用,具体是将类改为 USB ,即 Class=USB ,由于本驱动程序使用符号链接名打开设备,所以删除 ClassGUID 选项,注意设备标识符必需为: %DeviceDesc%=USBDIO_DDI, USBVID_0471&PID_0821 ,其中 0471 USB 控制芯片的厂商识别码, 0821 USB 设备标识码。

驱动程序安装过程是:将 USB 设备加电,连入计算机的 USB 接口,这时候会看到 Windows 操作系统提示发现新硬件,提问是否安装驱动程序,选择是,然后选择驱动程序所在文件夹,选择文件 USBDIO.INF 即可完成安装 .

2. USB 设备驱动程序的调用

为了完成对驱动程序的调用,使用 VC++6.0 编写 USB 应用程序包,程序包共由五个功能模块组成,用户通过调用这些模块即可方便的完成对 USB 外设的控制及读写,这些模块如下。

int CTRLReadData(unsigned char usbSelect unsigned char *rbuffer unsigned char numData) ,主要功能是读取 ISP1581 控制端点 0 发来的数据,数据存放在缓冲区 rbuffer 中。

int CTRLSendTestCommand (unsigned char usbSelect unsigned short int testCommand) ,主要功能是发送测试命令,变量 testCommand 定义了测试命令。

int CTRLSendDMACommand (unsigned char usbSelect unsigned char dmaDirection unsigned char ramSelect,unsigned long dmaLength) ,主要功能是发送 DMA 传输命令,变量 dmaDirection 定义数据传输方向, ramSelect 定义将要操作的 USB 外设的存储器, dmaLength 定义了数据传输总数。

int DMARead(unsigned char usbSelect unsigned char *rbuffer int len int waitTime) ,主要功能是计算机批量读取 ISP1581 中的数据,而 ISP1581 DMA 方式从外部 RAM 读取数据。

int DMAWrite(unsigned char usbSelect unsigned char *rbuffer int len int waitTime) ,主要功能是计算机批量写数据到 ISP1581 ,而 ISP1581 将以 DMA 方式写数据到外部 RAM

Windows下usb接口驱动技术(二)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论