55

Click here to load reader

第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

  • Upload
    ngotram

  • View
    275

  • Download
    13

Embed Size (px)

Citation preview

Page 1: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

“黑色经典”系列之《USB应用开发技术大全》

第 10章 DriverStudio驱动程序开发工具

本章目标

由于 USB设备的开发需要驱动程序的支持,因此高效的驱动程

序开发是 USB 设计的关键。目前开发驱动程序有 3 种方式:使用

Microsoft的 DDK工具、使用 KRFTech公司的 WinDriver工具和使

用 Compuware公司的 DriverStudio工具。

使用 Microsoft 的 DDK 开发驱动程序,比较复杂,类似于汇编

语言一样。为此,出现了一些简化驱动程序开发的软件工具,其中

比较出色的是 WinDriver 和 DriverStudio。WinDriver 软件比较简

单,可以快速创建驱动程序,但是对驱动程序的刻画不够细致。

DriverStudio 软件可以高效、细致地刻画驱动程序的每一个细节,

因此获得了广泛的应用。

本章主要讲解以下内容:

DriverStudio简介

WDM驱动程序建立实例 USB编程类函数

USB驱动创建实例

Page 2: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.1 DriverStudio简介

DriverStudio软件由 Compuware公司开发,用来简化微软Windows平台下设备驱动程序的开发、调试和测试。DriverStudio当前的版本为 V3.2,DriverStudio软件中的所有工具都与 Visual Studio IDE 环境集成在一起。开发人员可以在 Visual Studio 6.0、Visual Studio.NET 2002和 2003环境中编写并测试驱动程序,并且通过使用Microsoft C++编译器与Microsoft DDK完全保持兼容。

10.1.1 DriverStudio软件工具 DriverStudio软件包中包含多个驱动程序开发工具,主要的工具模块介绍如下。 1.DriverAgent DriverStudio 软件的 DriverAgent 开发工具为 Win32 应用程序提供直接访问硬件的功

能。用户可以在没有任何设备驱动程序开发经验的情况下编写 DriverAgent 应用程序来直接访问硬件设备。DriverAgent应用程序可以在Windows 95、Windows 98、Windows NT和Windows 2000平台上运行,但不支持Windows XP平台。

2.VToolsD

DriverStudio软件的 VToolsD工具用来开发Windows 95和Windows 98操作系统下设备驱动程序(VxD)。VToolsD中包括生成驱动程序源代码的工具 run-time和 interface库,以及一些驱动程序样本,可以用来作为各种类型的设备驱动程序的基础部分。

3.DriverWorks

DriverWorks对于Windows NT下和Windows 98与Windows 2000共同支持的Win32驱动模型(WDM)设备驱动程序的开发提供完全的支持。DriverWorks中包含一个非常完善的源代码生成工具(DriverWizard)以及相应的类库和驱动程序样本,它提供了在 C++下进行设备驱动程序开发的支持。

4.DriverNetworks

DriverNetworks 是针对 Windows 网络驱动开发人员的一个模块。在它的核心部分,DriverNetworks是一个针对 NDIS drivers和 TDI clients(DriverSockets)的 C++的类库。DriverNetworks 中也有 Quick Miniport Wizard 用来直接开始一个 NDIS Miniport 或Intermediate Driver工程。它可以快速生成所有采用 DriverNetworks C++类库编写的 NDIS驱动程序的编译,安装和调试所需要的文件。

5.Visual SoftICE

Visual SoftICE是一个双机的系统级调试器,提供了多窗口、可配置的图形化用户界面来帮助开发人员调试核心级的驱动程序、应用程序甚至于整个操作系统。Visual SoftICE的最新版本在性能、功能以及用户界面上都有很大提高,Visual SoftICE完全支持 AMD 64位的 Opteron和 Athlon64处理器所提供的新命令。

Page 3: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

SoftICE支持单机、用串行线连接的双机或是通过 TCP/IP连接的远程计算机上的核心级和用户级的调试。

6.BoundsChecker Driver Edition

BoundsChecker Driver Edition是一个错误侦测工具,可以实施分析和侦测设备驱动程序的错误。开发人员可以马上发现并修正这些错误,不用像以前那样要在数小时后才能完

成。新增的改进还有:开发人员修改程序设置之后无需重启计算机,让开发人员可以记录

驱动程序中的 user-written函数。开发人员可以清楚地看到开发中驱动程序的运行情况;可以查看 DriverWorkbench内置的事件页汇总信息,包括记录错误和泄漏问题并提供 SoftICE事件命令的新开关参数;可以标示 BoundsChecker 当前监视的驱动程序改进的自旋锁(spinlock)错误侦测。

BoundsChecker 驱动程序当前版本支持 Windows NT、Windows 2000、Windows Millennium Edition和Windows 98,但不支持Windows XP

7.DriverWorkbench

DriverWorkbench可以使用户进一步了解系统崩溃时的 dump文件和当时的事件。其与BoundsChecker Driver Edition集成在一起,在 DriverWorkbench中可以看到在系统崩溃前或其登录的时候由 BoundsChecker采集到的数据。这种独特的查看系统的方式使得开发人员可以通过查看系统崩溃之前系统实际活动的踪迹来发现问题之所在。

DriverWorkbench中也包含了 TrueTime Driver Edition。TrueTime Driver Edition是一个性能分析工具,用来改善驱动程序的性能问题,它可以准确地指出导致速度变慢的代码和

性能瓶颈。在 DriverStudio 3.2版本中,用户可以将两个或多个测试数据文件合并为一个,用来比较不同条件下改变代码所带来的性能提高情况。

DriverWorkbench当前支持 Windows NT和Windows 9x.,但不支持Windows XP。

8.FieldAgent

FieldAgent 可让开发人员对运行在客户的计算机上的驱动程序进行处理,由FieldAgent收集到的信息可用于追捕到那些可能只发生在特定的配置环境下问题的原因。

FieldAgent当前支持Windows NT和Windows 9x.(当前版本不支持Windows XP)。

9.TrueCoverage Driver Edition

TrueCoverage Driver Edition一个代码辅助工具,它可以在没有源代码和符号文件的情况下收集代码的辅助信息,驱动开发人员可以以图形化的方式查看代码结构。该工具同时

支持 NMS和 PDB符号文件,可以获取以下辅助数据:每个线程的基本信息,符合条件的辅助信息和部分执行的代码。

TrueCoverage可以检测代码中的哪些部分已经被测试,哪些部分还没有被测试。通过在开发过程中测量和跟踪代码的执行情况和稳定程度,可以节约测试时间并提高代码的可

靠性。TrueCoverage能够很轻松地收集驱动程序的覆盖率数据,在源代码的上下文中查看

Page 4: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

这些数据,也可以将多次会话的结果合并以累加覆盖率数据。 TrueCoverage Driver Edition当前支持Windows NT 4.0(Service Pack 3 or later)和Windows

2000,但不支持Windows XP。 在这些工具中,DriverWorks和 DriverNetworks是 DriverStudio的两个主要框架工具,

可以提高开发驱动程序的速度。DriverWorks 简化了开发 NT 和 WDM 驱动程序的工作,DriverNetworks则帮助开发人员毫不费力地创建和定制网络驱动程序。

DriverWorks和 DriverNetworks还都提供了全新的 DriverWizard,可以用 C语言来创建Windows设备驱动程序。另外,DriverWorks和 DriverNetworks还为 Visual Studio .NET提供了全新的菜单和工具条,开发人员可以使用Windows DDK编译器和链接器来 build驱动程序。

10.1.2 DriverSutdio软件的安装及配置 由于DriverSutdio对驱动程序的编译需要使用Microsoft的编译器,需要Windows DDK

支持。在安装 DriverSutdio软件之前,假定已经安装 Visual C++ 6.0以及Microsoft Windows XP的 DDK工具包。这里首先介绍 DriverSutdio软件的安装,操作步骤如下: (1)将安装光盘放入光驱中,此时自动弹出安装界面,如图 10.1所示。 (2)单击“Install DriverStudio host and/or target software”,开始进行 DriverSutdio集成

开发环境的安装,如图 10.2所示。

图 10.1 安装界面 图 10.2 开始安装软件

(3)单击“Next”按钮,弹出“License Agreement”对话框,如图 10.3所示。

Page 5: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

(4)选择“I accept the terms in the license Agreement”,并单击“Next”按钮。此时弹出输入用户信息对话框,如图 10.4所示。用户可以在其中输入用户名、公司名以及序列号。

图 10.3 “License Agreement”对话框 图 10.4 输入用户信息

(5)单击“Next”按钮,进入下一步,弹出“License Setup”对话框,如图 10.5所示。在其中选择“License File or Server”选项,单击“Browse”按钮选择一个 License文件。 (6)单击“Next”按钮,弹出“Destination folder”对话框,如图 10.6 所示。可以单

击“Change”按钮,来选择安装的目录。 (7)单击“Next”按钮,弹出“Select Machine Configuration”对话框,如图 10.7所示。

图 10.5 “License Setup”对话框 图 10.6 “Destination folder”对话框

(8)在其中选择“Both hort and target”选项,单击“Next”按钮,此时弹出“Select Features to Install”对话框,如图 10.8所示,可以在其中选择需要安装的开发工具。

Page 6: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.7 “Select Machine Configuration”对话框 图 10.8 “Select Features to Install”对话框

(9)单击“Next”按钮,弹出“Ready to Install the Program”对话框,如图 10.9所示。此时单击“Intall”按钮,便开始进行软件安装。 (10)在软件的安装过程中,会弹出“VtoolsD USER.MAK configuration”对话框,如

图 10.10所示,从中可以选择需要使用的编译工具。

图 10.9 “Ready to Install the Program”对话框 图 10.10 “Vtools USER.MAK configuration”对话框

(11)当安装完毕后,弹出“DriverStudio Configuration”对话框,如图 10.11所示。在其中可以进行 DriverStudio软件使用环境的设置,这里保持默认设置。

Page 7: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.11 “DriverStudio Configuration”对话框

(12)单击“Finish”按钮结束配置,此时弹出“Setup Wizard Completed”对话框,如图 10.12所示,单击“Finish”按钮结束软件安装。

图 10.12 “Setup Wizard Completed”对话框

10.1.3 配置 DriverSutdio编译环境 打开 Visual C++ 6.0编译环境,如图 10.13所示。在其中可以发现,Visual C++ 6.0编

程菜单栏上自动添加了“DriverStudio”菜单,并增加一个工具栏,用于执行 DriverStudio的编译操作。这样便于直接在 Visual C++ 6.0编译环境中进行驱动程序开发。

Page 8: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.13 Visual C++编译环境

软件安装完毕后,还需要对编译环境进行相应的设置,操作步骤如下: (1)在 Visual C++ 6.0编译环境中,选择“DriverStudio”→“DDK Build Settings”,弹

出对话框。在 DDK选项卡中设置 DDK的安装目录以及操作系统的环境,如图 10.14所示。 (2)在 DriverStudio选项卡中设置 DriverStudio的工作目录,如图 10.15所示。

图 10.14 设置 DDK编译环境 图 10.15 设置 DriverStudio的工作目录

(3)设置完成后,单击“OK”按钮,即可退出编译环境配置。

10.2 WDM驱动程序基本结构

在前面一章介绍了 WDM 驱动程序,这里介绍一下 DriverStudio环境下编写的 WDM驱动程序的框架。DriverStudio软件使用 DriverWorks进行WDM驱动程序开发,其对标准的WDM驱动程序进行了封装,简化了驱动程序开发的过程。

Page 9: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

在 DriverWorks创建的驱动程序中,使用了 3个封装类,分别为:KDriver、KPnpDevice和 KPnpLowerDevice。这几个类便可以完成WDM驱动程序的主要框架,下面分别进行介绍。

10.2.1 基类 KDriver KDriver 类负责WDM驱动程序的初始化以及目标设备对象的 IRP分发。在一个实际

的应用例程中,一般使用的是 KDriver类的派生类。该类在 DriverEntry例程中对驱动程序进行初始化,当 PnP子系统检测到设备的加载时,便调用 AddDevice例程。在 KDriver类中,还对 Unload等常用的例程进行了封装。

1.初始化例程 DriverEntry

任何一个 WDM 驱动程序都包含一个 DriverEntry 例程,用于驱动程序的初始化。在DriverWorks自动生成相应的 DriverEntry例程,示例代码如下所示:

NTSTATUS WriteFileDriver::DriverEntry(PUNICODE_STRING RegistryPath) { T.Trace(TraceInfo, __FUNCTION__"++. Compiled at " __TIME__ " on " __DATE__

"\n"); #ifdef DBG //DbgBreakPoint(); #endif NTSTATUS status = STATUS_SUCCESS; m_Unit = 0; // This macro suppresses compiler warning for unreferenced variable. // If you reference this parameter, simply remove the macro. UNREFERENCED_PARAMETER(RegistryPath); //注册地址字符

串 T.Trace(TraceInfo, __FUNCTION__"--. STATUS %x\n", status); //用于调试 return status; } 在这里,似乎看不到相应的初始化例程以及对 PnP IRP 的处理。其实已经在 KDriver

基类中进行了封装处理,并在 function.h 文件中进行了声明,代码示例如下,从中可以看出对常用的 IRP的声明:

// function.h

Page 10: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

// #ifndef __FUNCTION_H__ #define __FUNCTION_H__ #define DRIVER_FUNCTION_CREATE #define DRIVER_FUNCTION_CLOSE #define DRIVER_FUNCTION_DEVICE_CONTROL #define DRIVER_FUNCTION_CLEANUP #define DRIVER_FUNCTION_ADD_DEVICE #define DRIVER_FUNCTION_PNP #define DRIVER_FUNCTION_POWER #define DRIVER_FUNCTION_SYSTEM_CONTROL #define DRIVER_FUNCTION_UNLOAD #endif // __FUNCTION_H__

2.AddDevice例程

AddDevice例程也是WDM驱动程序所必需的,其用于创建一个设备对象作为目标 I/O设备。在 AddDevice例程中,将设备对象连接到设备堆栈中。当一个新设备连接到计算机上的时候,系统调用 AddDevice例程,该例程中进行如下步骤的处理: (1)创建设备对象,同时创建一个私有的设备扩展。 (2)保存设备接口,给出设备名并创建符号链接名。 (3)初始化设备扩展及设备对象。 (4)将新的设备对象连接到设备堆栈中。 DriverWorks生成的 AddDevice例程进行完整的封装,简化了用户的设计工作。Driver

Works的 AddDevice例程示例如下所示: NTSTATUS WriteFileDriver::AddDevice(PDEVICE_OBJECT Pdo) { T.Trace(TraceInfo, __FUNCTION__"++.\n"); NTSTATUS status = STATUS_SUCCESS; //创建一个 KDevice类的新类 WriteFileDevice,用于系统中存储类实例 WriteFileDevice* pDevice = new ( NULL, FILE_DEVICE_UNKNOWN, NULL, 0,

Page 11: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

DO_DIRECT_IO //Direct IO模式 | DO_POWER_PAGABLE ) //创建设备对象 WriteFileDevice(Pdo, m_Unit); //将设备对象连接到堆栈 if (pDevice == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; } else { status = pDevice->ConstructorStatus(); if (!NT_SUCCESS(status)) { delete pDevice; } else { m_Unit++; pDevice->ReportNewDevicePowerState(PowerDeviceD0);//报告电源

状态 } } T.Trace(TraceInfo, __FUNCTION__"--. STATUS %x\n", status); //用于调试 return status; } 10.2.2 即插即用类 KPnPDevice KPnPDevice类用于处理 IRP_MJ_PNP即插即用 IRP和 IRP_MJ_POWER电源管理 IRP。

KPnPDevice 类是 KDevice 类的派生类,提供了与应用程序的接口,用于主要的 IRP 分发任务。DriverWorks产生的主要 PnP例程的如下。

1.基本 PnP例程

DriverWorks在创建驱动程序时自动生成了一个默认的 PnP例程 DefaultPnp,另外,还创建了 3个必须的 PnP例程 OnStartDevice、OnStopDevice和 OnRemoveDevice,分别用于启动、停止和删除设备,其示例代码如下所示:

NTSTATUS WriteFileDevice::DefaultPnp(KIrp I)

Page 12: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

{ T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); T << I; I.ForceReuseOfCurrentStackLocationInCalldown(); NTSTATUS status = m_Lower.PnpCall(this, I); T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; } NTSTATUS WriteFileDevice::OnStartDevice(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; I.Information() = 0; //从 IRP中获得原始资源 PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources(); //从 IRP中获得传输的资源 PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources(); // TODO:添加用户代码 T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; } NTSTATUS WriteFileDevice::OnStopDevice(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS;

Page 13: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

// TODO:添加用户代码 //释放系统资源 Invalidate(); T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, STATUS _SUCC

ESS); return STATUS_SUCCESS; } NTSTATUS WriteFileDevice::OnRemoveDevice(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; // TODO: 添加用户代码 //释放系统资源 Invalidate(); T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, STATUS _SUCC

ESS); return STATUS_SUCCESS; }

2.Power例程

WDM驱动程序可以使用 IRP来进行电源管理,但并不是所有的设备都需要支持电源管理。如果不需要进行电源管理,则仅使用 DriverWorks 生成的默认电源管理例程DefaultPower即可,程序示例代码如下所示:

NTSTATUS WriteFileDevice::DefaultPower(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); T << I; I.IndicatePowerIrpProcessed(); I.CopyParametersDown();

Page 14: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

NTSTATUS status = m_Lower.PnpPowerCall(this, I); T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; } 3.扩展例程 WDM驱动程序可以通过分发例程来和主机程序进行通信。其中 Create例程用于创建

设备对象接口,Close 例程用于关闭接口,DeviceControl 例程用于接口程序处理。这些分发例程是必须的,其示例代码如下所示:

NTSTATUS WriteFileDevice::Create(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; I.Information() = 0; I.PnpComplete(this, status); //完成 IRP T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; } NTSTATUS WriteFileDevice::Close(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; I.Information() = 0; I.PnpComplete(this, status); //完成 IRP T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; } NTSTATUS WriteFileDevice::DeviceControl(KIrp I)

Page 15: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

{ T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; switch (I.IoctlCode()) //IOCTL代码 { case IOCTL_800: status = IOCTL_800_Handler(I); //执行操作 break; case IOCTL_801: status = IOCTL_801_Handler(I); //执行操作 break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } if (status != STATUS_PENDING) { I.PnpComplete(this, status); } T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; } 10.2.3 物理对象类 KPnpLowerDevice KPnpLowerDevice 类是 KLowerDevice 类的派生类,其提供了物理设备对象的模型。

KPnpLowerDevice类用于创建和初始化一个 KPnpLowerDevice类实例,并将其连接到相应的物理设备对象上。可以使用如下的函数构造 KPnpLowerDevice类实例,并进行初始化。

KPnpLowerDevice m_Lower; m_Lower.Initialize(this,Pdo);

Page 16: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.3 WDM驱动程序建立实例

这里通过一个实例介绍使用 DriverWorks 进行驱动程序开发的流程。为了简单起见,这里创建一个无需硬件支持的驱动程序,这样可以方便读者的学习。在本例中,通过驱动

程序来实现文件的读写。 10.3.1 简单驱动程序的建立 首先使用 DriverWorks提供的 DriverWizard工具进行驱动程序框架的建立,同时也将

建立一个测试的主机应用程序,操作步骤如下: (1)在 Visual C++ 6.0中,选择“DriverStudio”→“DriverWizard”,弹出“DriverWizard”

对话框,如图 10.16所示,开始一步一步进行驱动程序创建。

图 10.16 “DriverWizard”对话框

(2)这里需要创建一个新的驱动程序,因此,单击“Start a New Driver Project”。此时弹出对话框,如图 10.17所示。

图 10.17 输入项目名称

Page 17: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

(3)该对话框左边显示了整个过程可以分为 12 个步骤,这是第一步,首先需要输入项目名称,例如“KfileWrite”,以及项目的保存路径。图中还显示了采用的是 Visual Studio 6和 DDK进行程序开发。当然也可以使用 Visual Studio.NET进行程序设计。 (4)单击“Next”按钮,进入下一步,如图 10.18 所示。在其中选择该项目的类型,

可以支持WDM Driver、Kernel Mode Service、NDIS Driver和 AVStream Minidriver。这里选择“WDM Driver”即可,并且选择“DriverWorks C++ Framework”选项。

图 10.18 选择项目的类型

(5)单击“Next”按钮,进入下一步,如图 10.19所示。在这里可以选择驱动的类型,

图 10.19 选择驱动程序的类型

Page 18: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

支持WDM Function Driver、WDM Filter Driver、WDM Bus Device、HID Minidriver、Virtual Serial Driver和 Virtual SCSI Port Driver。这里需要编写的是一个功能设备驱动程序,因此,选择“WDM Function Driver”选项即可。 (6)单击“Next”按钮,进入下一步,如图 10.20 所示。在这里可以选择硬件总线的

类型,支持 None、PCI、USB、IEEE 1394和其他总线类型。本例中创建一个无需硬件支持的驱动程序,因此,选择“None”选项即可。

图 10.20 选择硬件总线

(7)单击“Next”按钮,进入下一步,如图 10.21 所示。在这里可以选择需要处理的IRP类型。其中支持多种主要的 IRP、Minor Pnp和其他一些 IRP,这里保持默认选择即可。

Page 19: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.21 IRP处理

(8)单击“Next”按钮,进入下一步,如图 10.22 所示。在这里可以创建驱动程序的I/O接口,包括 IRP_MJ_READ、IRP_MJ_WRITE和自定义的 IOCTL请求。其中可以选择设备是采用接口还是符号链接名来识别。

图 10.22 创建 I/O

(9)这里创建一个自定义的 IOCTL请求接口来实现文件的读写。单击“Add”按钮,弹出“Add IO Control Code”对话框,如图 10.23 所示。在其中输入 Parameter Name 为“IOCTL_800”,Ordinal为“0x800”,Access选择为“Write”。

图 10.23 “Add IO Control Code”对话框

(10)单击“OK”按钮,完成 IOCTL 请求接口的添加,并返回到原来的界面,如图10.24所示。 (11)单击“Next”按钮,进入下一步,如图 10.25 所示。在这里可以添加注册表

入口变量,添加的数据将保存在系统注册表中。单击“Add”按钮即可添加,这里不需要设置。

Page 20: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.24 添加 IOCTL请求接口

图 10.25 注册表入口

(12)单击“Next”按钮,进入下一步,如图 10.26所示。在这里可以进行电源管理,这里选择“Manage power for this device”选项即可。 (13)单击“Next”按钮,进入下一步,如图 10.27所示。这里可以设置是否支持WMI

属性,本例不需要支持WMI,因此不用选择。

Page 21: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.26 电源管理

图 10.27 WMI属性

(14)单击“Next”按钮,进入下一步,如图 10.28所示。在这里可以进行驱动程序安装过程中的设置,即对 INF文件进行配置。按照图中输入各个参数,并选择“Generate Class Installer DLL”选项即可。

Page 22: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.28 INF文件设置

(15)单击“Next”按钮,进入下一步,如图 10.29所示。在这里可以进行附加设置,例如产生 AMD64示例项目、产生 SoftICE NMS文件等。这里保持默认设置即可。

图 10.29 附加设置

(16)单击“Next”按钮,进入下一步,如图 10.30所示。在这里列出了该项目中的所有的设置参数。如果需要进行修改,可以单击“Back”按钮,返回前面的步骤进行修改。

Page 23: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.30 项目参数列表

(17)如果项目创建无误,则可以单击“Finish”按钮,结束驱动程序项目的建立。 10.3.2 驱动程序设计 前面使用 DriverWorks的 DriverWizard工具建立了WDM驱动程序的框架。其中,大

部分的 IRP处理代码都已经自动创建,但是还需要进行一些用户自定义请求的建立。

1.KPnpDevice例程

在 KPnpDevice 例程中需要进行设备的初始化等操作,如对设备对象进行管理、设置即插即用策略、设置电源策略等,其示例代码如下所示:

KFileWriteDevice::KFileWriteDevice(PDEVICE_OBJECT Pdo, ULONG Unit) : KPnpDevice(Pdo, &GUID_DEVINTERFACE_KFILEWRITE) { if (!NT_SUCCESS(m_ConstructorStatus)) { T.Trace(TraceError, __FUNCTION__": Failed to create device Kfile Write

Device" " unit number %d status %x\n", Unit, m_ConstructorStatus); ASSERT(FALSE); return; } //初始化设备 m_Lower.Initialize(this, Pdo);

Page 24: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

SetLowerDevice(&m_Lower); //初始化标准即插即用策略 SetPnpPolicy(); // TODO: 用户可以设置自定义 PNP策略 //初始化标准电源策略 SetPowerPolicy(); // TODO: 用户可以添加自定义操作 }

2.自定义 IOCTL接口设计

在前面定义了一个自定义的 IOCTL 接口,用于读写文件,这里便介绍如何在程序中使用这个自定义的 IOCTL 接口。自定义 IOCTL 的处理放置在 DeviceControl 函数中,由switch语句进行判断,如果主机程序向驱动程序发送 IOCTL_800请求,则执行相应的处理。程序的示例代码如下:

NTSTATUS KFileWriteDevice::DeviceControl(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; switch (I.IoctlCode()) //IOCTL代码 { case IOCTL_800: //对自定义的 IOCTL进行处理 status = IOCTL_800_Handler(I); //调用 IOCTL_800_Handler函数 break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } if (status != STATUS_PENDING)

Page 25: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

{ I.PnpComplete(this, status); } T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; //返回状态 } 该段程序中,如果遇到 IOCTL_800请求,则调用 IOCTL_800_Handler()函数进行处

理。所有的程序处理代码放置在 IOCTL_800_Handler()函数中进行。IOCTL_800_Handler()函数的示例代码如下:

NTSTATUS KFileWriteDevice::IOCTL_800_Handler(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; ULONG inputSize = I.IoctlInputBufferSize(); //初始化变量 ULONG outputSize = I.IoctlOutputBufferSize(); PVOID inputBuffer = I.IoctlBuffer(); PVOID outputBuffer = I.IoctlBuffer(); UCHAR buf; ULONG size; ULONG pnWritten; KFile m_File; //定义文件变量 KUstring name(L"\\DosDevices\\d:\\KFileWrite"); //文件保存位置 status=m_File.OpenCreate(name, //打开文件 NULL, FILE_GENERIC_WRITE|SYNCHRONIZE, OBJ_CASE_INSENSITIVE, 0, FILE_SHARE_WRITE, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);

Page 26: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

buf='a'; //待写入的字符 size=1; m_File.Write(&buf,size,&pnWritten,NULL); //执行写操作 T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP

%p, STATUS %x\n", I, status); return status; //返回状态 } 程序中,首先初始化输入/输出变量空间、定义文件并创建相应的文件,保存在 D盘,

命名为“KfileWrite”。程序执行时,将 buf中的字符“a”写入到该文件中。

3.主机测试程序

在使用 DriverWorks的 DriverWizard工具建立了WDM驱动程序的框架的时候,已经建立了一个主机测试程序,其界面如图 10.31 所示。其中对各个按钮都已经有了详细的程序代码,可以直接编译运行,也可以添加自己的程序代码。

图 10.31 主机测试程序界面

程序编写完毕后,便可以进行编译,并生成相应的驱动程序和主机测试程序。

10.3.3 驱动程序的安装

驱动程序和主机测试程序编译通过后,还不能直接使用。因为主机测试程序和驱动程

序进行通信需要安装相应的驱动程序才能运行。因此,这里首先安装前面生成的驱动程序,

驱动程序安装的操作步骤如下:

Page 27: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

(1)打开系统的控制面板,如图 10.32 所示。在其中双击“添加硬件”图标,可以手动安装驱动程序。

图 10.32 系统控制面板

(2)此时弹出“添加硬件向导”对话框,如图 10.33所示。 (3)单击“下一步”按钮,系统便开始搜索连接到硬件设备。因为这里的驱动程序不

需要硬件支持,因此,系统找不到新硬件,便弹出对话框询问硬件连接,如图 10.34所示。

图 10.33 “添加硬件向导”对话框 图 10.34 询问硬件连接

(4)在其中选择“是,我已经连接了此硬件”,单击“下一步”按钮。此时弹出安装的硬件列表对话框,如图 10.35所示,在其中选择“添加新的硬件设备”即可。 (5)单击“下一步”按钮,弹出对话框,如图 10.36 所示。这里选择“安装我手动从

列表选择的硬件(高级)”,即采用手动安装驱动程序。 (6)单击“下一步”按钮,弹出对话框,如图 10.37 所示。在这里可以选择安装的设

备类型,这里选择“显示所有设备”即可。

Page 28: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.35 安装的硬件列表 图 10.36 手动安装驱动程序

(7)单击“下一步”按钮,弹出对话框,如图 10.38所示。在这里单击“从磁盘安装”按钮,可以选择前面生成的驱动程序进行安装。

图 10.37 选择安装的设备类型 图 10.38 手动选择驱动程序

(8)选择驱动程序后,返回原界面,如图 10.39 所示。其中已经显示了待安装的驱动程序的名称信息。 (9)单击“下一步”按钮,弹出对话框,如图 10.40 所示。此时可以单击“下一步”

按钮,开始执行驱动程序的安装。

图 10.39 待安装的驱动程序 图 10.40 安装驱动

Page 29: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

(10)驱动安装完毕后,弹出对话框,如图 10.41所示。单击“完成”按钮即可结束驱动程序的安装。 驱动程序安装完毕后,便可以打开设备管理器,在其中可以看到新安装的驱动程序,

如图 10.42所示。双击该设备,可以查看相应的设备信息。

图 10.41 完成驱动程序安装 图 10.42 设备管理器

10.3.4 驱动程序测试 程序编译生成的主机测试程序的名称为“KFileWriteApp.exe”。双击该程序打开测试程

序,如图 10.43 所示,其中列出了对应驱动程序的接口。下面开始进行驱动程序测试,操作步骤如下:

图 10.43 主机测试程序

(1)单击该驱动程序的接口名称,表示选择该驱动程序进行测试。 (2)单击“Open Handle”按钮,打开该设备,如图 10.44所示。 (3)在“Operation Type”中选择“IOCTL_800”,并单击“Execute Transfer”按钮,

执行 IOCTL请求传输。程序执行完毕后,在系统的 D盘根目录下,创建一个“KfileWrite”文件。在该文件中写入了字符“a”,可见该驱动程序工作正常。 (4)驱动程序测试完毕后,单击“Close Handle”按钮关闭设备,便可以退出该驱动测

试程序。

Page 30: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.44 打开该设备

图 10.45 执行 IOCTL测试

10.4 USB编程类函数概述

在 DriverWorks中提供了 3个 USB设备开发类,这 3个类的说明如下: • KUsbLowerDevice类,用于 USB设备的编程。 • KUsbInterface类,用于 USB接口的编程。 • KUsbPipe类,用于 USB管道的编程。 这些类中定义了很多 USB控制和数据传输的成员函数,是 USB驱动程序设计的基础。

下面分别介绍这些控制函数类。

10.5 USB设备编程类 KUsbLowerDevice

KUsbLowerDevice类由 KPnpLowerDevice类继承而来。KUsbLowerDevice类的实例代表 USB端点 0,允许 USB驱动程序通过端点 0的默认控制管道来配置 USB设备,读取和设置 USB状态等。下面分别介绍主要的控制成员函数。

Page 31: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.5.1 激活 USB设备配置函数 ActivateConfiguration ActivateConfiguration函数在即插即用的开始例程中使用,用于激活指定的 USB 设备

配置。ActivateConfiguration函数的声明格式示例如下: AC_STATUS ActivateConfiguration( USHAR ConfigurationValue, ULONG MaxConfigSize=1024 ); 其中 ConfigurationValue为配置号,从 1开始;MaxConfigSize为存放 USB配置描述符

的最大存储空间大小,以字节为单位。其典型的应用实例代码示例如下: m_UsbLowerDevice.Initialize(this, Pdo); // 初 始 化

KUsbLowerDevice m_KUsbInterface1.Initialize(m_UsbLowerDevice, 0, 1, 0); // 初 始 化 Kusb

Interface m_KUsbPipeIN.Initialize(m_UsbLowerDevice, 0x81); //初始化 IN管道 m_KUsbPipeOUT.Initialize(m_UsbLowerDevice, 0x2); //初始化 OUT管道 acStatus = m_UsbLowerDevice.ActivateConfiguration(1); //配置值为 1 10.5.2 终止 USB设备配置函数 DeActivateConfiguration DeActivateConfiguration函数用于终止当前 USB设备的配置,一般用于即插即用的停

止例程。DeActivateConfiguration函数的定义格式示例如下: NTSTATUS DeActivateConfiguration( PIO_COMPLETION_ROUTINE pfnCompletionRoutine=NULL, PVOID pContext=NULL ); 其中 pfnCompletionRoutine为完成 PnP例程,pContext为传递给完成例程的环境参数。 10.5.3 初始化厂商请求函数 BuildVendorRequest BuildVendorRequest函数用于初始化一个 USB厂商请求 URB,其定义格式示例如下: PURB BuildVendorRequest( PUCHAR TransferBuffer, ULONG TransferBufferLength, UCHAR RequestTypeReservedBits, UCHAR Request, USHORT Value, BOOLEAN bIn=FALSE,

Page 32: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

BOOLEAN bShortOk=FALSE, PURB Link=NULL UCHAR Index=0, USHORT Function=URB_FUNCTION_VENDOR_DEVICE, PURB pUrb=NULL ); 其中,TransferBuffer 为数据存放缓冲区;TransferBufferLength 为传输的字节数;

RequestTypeReservedBits为 USB请求字节中的保留位;Request为请求码;Value为数值;bIn 为数据传输方向,TRUE 表示数据由设备到主机,FALSE 表示数据由主机到设备;bShortOk 为传输字节控制,为 TRUE 表示传输的字节数可以少于应指定的字节数;Link表示连接的下一个厂商请求 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.5.4 分配类请求函数 BuildClassRequest BuildClassRequest函数用于分配一个用于类请求的 URB,并对 USB设备进行初始化。

其定义格式示例如下: PURB BuildClassRequest( PUCHAR TransferBuffer, ULONG TransferBufferLength, UCHAR RequestTypeReservedBits, UCHAR Request, USHORT Value, BOOLEAN bIn=FALSE, BOOLEAN bShortOk=FALSE, PURB Link=NULL, UCHAR Index=0, USHORT Function=URB_FUNCTION_CLASS_DEVICE, PURB pUrb=NULL ); 其中,TransferBuffer 为数据存放缓冲区;TransferBufferLength 为传输的字节数;

RequestTypeReservedBits为 USB请求字节中的保留位;Request为请求码;Value为数值;bIn 为数据传输方向,TRUE 表示数据由设备到主机,FALSE 表示数据由主机到设备;bShortOk 为传输字节控制,为 TRUE 表示传输的字节数可以少于应指定的字节数;Link表示连接的下一个类请求 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.5.5 清除特征标志函数 ClearFeature ClearFeature函数执行时分配一个 URB并将其发送到 USB总线驱动程序,清除一个特

征标志。ClearFeature函数的定义格式示例如下:

Page 33: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

NTSTATUS ClearFeature( USHORT Feature, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,Feature为特征值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。 10.5.6 设置特征标志函数 SetFeature SetFeature函数执行时,分配一个 URB,并将其发送到 USB总线驱动程序,设置一个

特征标志。SetFeature函数的定义格式示例如下: NTSTATUS SetFeature( USHORT Feature, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,Feature为特征值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。 10.5.7 获取状态函数 GetStatus GetStatus函数执行时,分配一个 URB,并将其发送到 USB总线驱动程序,用于获取

状态信息。GetStatus函数的定义格式示例如下: NTSTATUS GetStatus( PUSHORT pStatus, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,pStatus为状态值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。 10.5.8 获取 USB帧号函数 GetCurrentFrameNumber GetCurrentFrameNumber函数用于获取当前 USB的帧号,其定义格式示例如下: ULONG GetCurrentFrameNumber( VOID); 其典型的使用示例代码如下: ULONG FName; FName=GetCurrentFrameNumber();

Page 34: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.5.9 未配置状态函数 Unconfigure Unconfigure函数用于将设备置于未配置状态,Unconfigure函数的定义格式示例如下: NTSTATUS Unconfigure( PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,CompletionRoutine为完成例程;pContext为传递给完成例程的环境参数。 10.5.10 配置状态函数 Configure Configure函数用于将设备置于配置状态,Configure函数的定义格式示例如下: NTSTATUS Configure(void); 其典型的使用示例代码如下: NTSTATUS State; State=Configure(); 10.5.11 配置接口函数 PreconfigureInterface PreconfigureInterface 函数用于指定需要进行配置的接口和相应 USB 管道名称。

PreconfigureInterface函数的定义格式如下: NTSTATUS PreconfigureInterface( PUSB_INTERFACE_DESCRIPTOR

pInterfaceDesc ); 其典型的使用示例代码如下: NTSTATUS PreState; PreState=PreconfigureInterface(pInterfaceDesc); 10.5.12 接口描述符函数 LocateInterface LocateInterface 函数用于读取并返回 USB 接口描述符。LocateInterface 函数的定义格

式示例如下: PUSB_INTERFACE_DESCRIPTOR LocateInterface( PVOID* pStart, PUSB_ENDPOINT_DESCRIPTOR* ppEndpoints, LONG InterfaceNumber = -1, LONG AlternateSetting = -1, LONG InterfaceClass = -1, LONG InterfaceSubClass = -1, LONG InterfaceProtocol = -1 ); 其中, pStart 为地址指针; ppEndpoints 用于存放属于该接口的端点阵列;

InterfaceNumber为接口索引号;AlternateSetting为要选择的接口设置值;InterfaceClass为

Page 35: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

接口类的值;InterfaceSubClass为接口子类的值;InterfaceProtocol为接口协议值。 10.5.13 配置描述符函数 Preconfigure Preconfigure函数用于读取并返回 USB设备的配置描述符,Preconfigure函数定义格式

示例如下: NTSTATUS Preconfigure( UCHAR ConfigIndex=0, ULONG MaxConfigSize=DEFAULT_CONFIG_SIZE ); 其中,ConfigIndex表示需要读取的设备配置描述符的索引号;MaxConfigSize为申请

的用于的存放配置描述符的缓冲区字节数。 10.5.14 删除 USB资源函数 ReleaseResources ReleaseResources函数在 PnP删除例程中使用,用于删除已分配的 USB资源。Release

Resources函数的定义格式如下: void ReleaseResources(void); 其典型的使用示例代码如下: ReleaseResources(); 10.5.15 字符串描述符函数 GetStringDescriptor GetStringDescriptor 函数用于读取并返回字符串描述符,GetStringDescriptor 函数的定

义格式示例如下: NTSTATUS GetStringDescriptor( UCHAR Index, PSTR pStr, LONG MaxLen, SHORT LangId ); 其中,Index为字符串的索引号;pStr为存放字符串的首地址;MaxLen为字符串的最

大字节数;LangId为语言 ID号。 10.5.16 设备描述符函数 GetDeviceDescriptor GetDeviceDescriptor函数用于读取并返回 USB设备描述符,GetDeviceDescriptor函数

的定义格式示例如下:

Page 36: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

NTSTATUS GetDeviceDescriptor( PUSB_DEVICE_DESCRIPTOR pDevDesc ); 其中,pDevDesc用于存放 USB设备描述符变量地址。 10.5.17 初始化函数 Initialize Initialize函数用于初始化一个 KUsbLowerDevice类实例,Initialize函数的定义格式如

下: NTSTATUS Initialize( KDevice* AttachingDevice, PDEVICE_OBJECT PhysicalDeviceObject ); 该函数的使用示例代码如下: KUsbLowerDevice m_UsbLowerDevice; m_UsbLowerDevice.Initialize(this, Pdo); //初始化 KUsbLowerDevice 10.5.18 发送 URB函数 SubmitUrb SubmitUrb函数用于将 URB发送到 USB主机驱动程序中进行处理。SubmitUrb函数的

定义格式示例如下: NTSTATUS SubmitUrb( PURB pUrb, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID CompletionContext=NULL, ULONG mSecTimeOut=0 ); 其中,pUrb为创建的 URB;CompletionRoutine为完成例程;CompletionContext为传

递给完成例程的环境参数;mSecTimeOut为同步调用定时参数,以 ms为单位。

10.6 USB接口编程类 KUsbInterface

KUsbInterface类用于 USB接口编程,可以使用其获取接口和 USB管道的信息。下面分别介绍该类的成员函数。

10.6.1 使能接口函数 SelectAlternate SelectAlternate函数用于重新使能指定的接口,SelectAlternate函数的定义格式如下: SA_STATUS SelectAlternate( UCHAR AlternateSetting ); 其中,AlternateSetting表示选择的接口号。

Page 37: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.6.2 清除特征标志函数 ClearFeature ClearFeature函数用于函数执行时分配一个 URB并将其发送到 USB总线驱动程序,清

除一个特征标志。ClearFeature函数的定义格式示例如下: NTSTATUS ClearFeature( USHORT Feature, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,Feature为特征值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。 10.6.3 设置特征标志函数 SetFeature SetFeature 函数执行时分配一个 URB 并将其发送到 USB 总线驱动程序,设置一个特

征标志。SetFeature函数的定义格式示例如下: NTSTATUS SetFeature( USHORT Feature, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,Feature为特征值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。 10.6.4 获取状态函数 GetStatus GetStatus函数执行时分配一个 URB并将其发送到 USB总线驱动程序,用于获取状态

信息。GetStatus函数的定义格式示例如下: NTSTATUS GetStatus( PUSHORT pStatus, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,pStatus为状态值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。 10.6.5 初始化厂商请求函数 BuildVendorRequest BuildVendorRequest函数用于初始化一个 USB厂商请求 URB,其定义格式示例如下:

Page 38: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

PURB BuildVendorRequest( PUCHAR TransferBuffer, ULONG TransferBufferLength, UCHAR RequestTypeReservedBits, UCHAR Request, USHORT Value, BOOLEAN bIn=FALSE, BOOLEAN bShortOk=FALSE, PURB Link=NULL UCHAR Index=0, USHORT Function=URB_FUNCTION_VENDOR_DEVICE, PURB pUrb=NULL ); 其中,TransferBuffer为数据存放缓冲区;TransferBufferLength为传输的字节数;Request

TypeReservedBits为 USB请求字节中的保留位;Request为请求码;Value为数值;bIn为数据传输方向,TRUE表示数据由设备到主机,FALSE表示数据由主机到设备;bShortOk为传输字节控制,为 TRUE表示传输的字节数可以少于应指定的字节数;Link表示连接的下一个厂商请求 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的URB。

10.6.6 分配类请求函数 BuildClassRequest BuildClassRequest函数用于分配一个用于类请求的 URB,并对 USB设备进行初始化,

其定义格式示例如下: PURB BuildClassRequest( PUCHAR TransferBuffer, ULONG TransferBufferLength, UCHAR RequestTypeReservedBits, UCHAR Request, USHORT Value, BOOLEAN bIn=FALSE, BOOLEAN bShortOk=FALSE, PURB Link=NULL, UCHAR Index=0, USHORT Function=URB_FUNCTION_CLASS_DEVICE, PURB pUrb=NULL ); 其中,TransferBuffer 为数据存放缓冲区;TransferBufferLength 为传输的字节数;

RequestTypeReservedBits为 USB请求字节中的保留位;Request为请求码;Value为数值;

Page 39: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

bIn 为数据传输方向,TRUE 表示数据由设备到主机,FALSE 表示数据由主机到设备;bShortOk 为传输字节控制,为 TRUE 表示传输的字节数可以少于应指定的字节数;Link表示连接的下一个类请求 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.6.7 管道函数 Pipes Pipes函数用于指定接口的管道,Pipes函数的定义格式如下: PUSBD_PIPE_INFORMATION Pipes( int Index=0 ); 10.6.8 管道数量函数 NumberOfPipes NumberOfPipes 函数用于读取并返回当前接口的管道数量,NumberOfPipes 函数的定

义格式如下: ULONG NumberOfPipes( void ); 其典型的使用示例代码如下: ULONG NumPipe; NumPipe= NumberOfPipes(); 10.6.9 接口协议函数 Protocol Protocol函数用于读取并返回接口的协议值,Protocol函数的定义格式如下: UCHAR Protocol(void); 其典型的使用示例代码如下: UCHAR CPro; CPro= Protocol(); 10.6.10 接口子类函数 Subclass Subclass函数用于读取并返回接口的子类值,Subclass函数的定义格式如下: UCHAR Subclass(void); 其典型的使用示例代码如下: UCHAR CSub; CSub=SubClass(); 10.6.11 接口类函数 Class Class函数用于读取并返回接口的类值,Class函数的定义格式如下: UCHAR Class(void); 其典型的使用示例代码如下: UCHAR CCla; CCla=Class();

Page 40: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.6.12 使能接口号函数 AlternateSetting AlternateSetting 函数用于读取并返回当前使能的接口号,AlternateSetting 函数的定义

格式示例如下: UCHAR AlternateSetting(void); 其典型的使用示例代码如下: UCHAR CAlset; CAlset=AlteranateSetting(); 10.6.13 接口数量函数 InterfaceNumber InterfaceNumber 函数用于读取并返回 USB 设备的接口数量,InterfaceNumber 函数的

定义格式示例如下: UCHAR InterfaceNumber(void); 其典型的使用示例代码如下: UCHAR CInt; CInt=InterfaceNumber(); 10.6.14 初始化函数 Initialize Initialize函数用于创建一个 KUsbInterface类实例,Initialize函数函数的定义格式如下: NTSTATUS Initialize( KUsbLowerDevice& Device, UCHAR InterfaceNumber, UCHAR ConfigurationValue, UCHAR InitialAlternateSetting ); 其中, Device 为 KUsbInterface 类实例名称; InterfaceNumber 为接口号;

ConfigurationValue为配置值;InitialAlternateSetting为初始化配置的接口号。 10.6.15 关闭接口函数 Close Close函数用于关闭一个打开的接口类,Close函数的定义格式如下: VOID Close( VOID ); 其典型的使用示例代码如下: Close(); 10.6.16 是否打开函数 IsOpen IsOpen函数用于测试 KUsbInterface类实例是否打开,IsOpen函数的定义格式如下: BOOLEAN IsOpen(void);

Page 41: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

其典型的使用示例代码如下: BOOLEAN bOpen; bOpen=IsOpen(); if (bOpen) AfxMessageBox(“实例打开!”); else AfxMessageBox(“实例未打开!”); 10.6.17 打开实例函数 Open Open函数用于打开 KUsbInterface类实例,Open函数的定义格式如下: NTSTATUS Open(VOID); 其典型的使用示例代码如下: NTSTATUS ntOpen; ntOpen=Open(); 10.6.18 发送 URB函数 SubmitUrb SubmitUrb函数用于将 URB发送到 USB主机驱动程序中进行处理,SubmitUrb函数的

定义格式示例如下: NTSTATUS SubmitUrb( PURB pUrb, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID CompletionContext=NULL, ULONG mSecTimeOut=0 ); 其中,pUrb为创建的 URB;CompletionRoutine为完成例程;CompletionContext为传

递给完成例程的环境参数;mSecTimeOut为同步调用定时参数,以 ms为单位。 10.6.19 是否可用函数 IsValid IsValid函数用于测试 KUsbInterface类实例是否可用,IsValid函数的定义格式如下: BOOLEAN IsValid( void ); 其典型的使用示例代码如下: BOOLEAN bVal; bVal=IsValid();

10.7 USB管道编程类 KUsbPipe KUsbPipe类用于 USB管道的编程。管道是 USB主机和 USB端点的信息通道,下面

分别介绍其成员函数。

Page 42: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.7.1 初始化函数 Initialize Initialize函数用于创建一个 KUsbPipe类实例,Initialize函数的定义格式如下: NTSTATUS Initialize ( KUsbLowerDevice& Device, UCHAR EndpointAddress, ULONG MaxTransferSize=0 ); 其中,Device 为 KUsbPipe 类实例;EndpointAddress 为 USB 端点的地址;

MaxTransferSize为当前管道最大传输字节数。 10.7.2 打开接口函数 Open Open函数用于打开接口的管道,Open函数的定义格式如下: NTSTATUS Open(KUsbInterface& Interface); 10.7.3 是否打开函数 IsOpen IsOpen函数用于测试指定的管道是否打开,IsOpen函数的定义格式如下: BOOLEAN IsOpen(void); 10.7.4 关闭管道函数 Close Close函数用于关闭指定的管道,Close函数的定义格式如下: VOID Close( VOID); 10.7.5 中断传输函数 BuildInterruptTransfer BuildInterruptTransfer 函数用于分配一个用于中断传输的 URB,并进行初始化。

BuildInterrupt Transfer函数的定义格式如下: PURB BuildInterruptTransfer( KMemory& Mdl, ULONG Length, BOOLEAN bShortOk=TRUE, PURB Link=NULL, PURB pUrb=NULL, BOOLEAN bIn=TRUE ); 其中,Mdl为存放传输数据的缓冲区;Length为传输的字节数;bShortOk为 TRUE则

表示传输的字节数可以小于指定值;Link表示连接的下一个传输的 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.7.6 控制传输函数 BuildControlTransfer BuildControlTransfer 函数用于分配一个用于控制传输的 URB,并进行初始化。

BuildControlTransfer函数的定义格式如下:

Page 43: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

PURB BuildControlTransfer( KMemory& Mdl, BOOLEAN bIn, ULONG Length, PURB Link=NULL, PURB pUrb=NULL ); 其中,Mdl为存放传输数据的缓冲区;Length为传输的字节数;bShortOk为 TRUE则

表示传输的字节数可以小于指定值;Link表示连接的下一个传输的 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.7.7 块传输函数 BuildBulkTransfer BuildBulkTransfer 函数用于分配一个用于块传输的 URB,并进行初始化。

BuildBulkTransfer函数的定义格式如下: PURB BuildBulkTransfer( KMemory& Mdl, ULONG Length, BOOLEAN bIn, PURB Link=NULL, BOOLEAN bShortOk=FALSE, PURB pUrb=NULL ); 其中,Mdl为存放传输数据的缓冲区;Length为传输的字节数;bShortOk为 TRUE则

表示传输的字节数可以小于指定值;Link表示连接的下一个传输的 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.7.8 同步传输函数 BuildIsochronousTransfer

BuildIsochronousTransfer 函数用于分配一个用于同步传输的 URB,并进行初始化。BuildIsochronousTransfer函数的定义格式如下:

PURB BuildIsochronousTransfer( ULONG NumberOfPackets, ULONG PacketSize, BOOLEAN bIn, BOOLEAN bASAP, ULONG StartFrame, PVOID Buffer, ULONG Length, PURB pUrb=NULL );

Page 44: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

其中,NumberOfPackets为传输包的数量;PacketSize为传输包的字节数;bIn为传输

方向,TRUE 表示数据由设备到主机,FALSE 表示数据由主机到设备;bASAP 置 TRUE表示最快的方式开始传输;StartFrame 表示传输的起始帧号;Buffer 为驱动程序存放数据的缓冲区;Length表示传输的字节数;pUrb表示分配一个新的 URB。

10.7.9 清除特征标志函数 ClearFeature

ClearFeature函数执行时分配一个 URB,并将其发送到 USB总线驱动程序,清除一个特征标志,ClearFeature函数的定义格式示例如下:

NTSTATUS ClearFeature( USHORT Feature, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,Feature为特征值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。

10.7.10 设置特征标志函数 SetFeature

SetFeature函数执行时,分配一个 URB,并将其发送到 USB总线驱动程序,设置一个特征标志。SetFeature函数的定义格式示例如下:

NTSTATUS SetFeature( USHORT Feature, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,Feature为特征值;CompletionRoutine为完成例程;pContext为传递给完成例程

的环境参数。 10.7.11 获取状态函数 GetStatus

GetStatus函数执行时,分配一个 URB,并将其发送到 USB总线驱动程序,用于获取状态信息。GetStatus函数的定义格式示例如下:

NTSTATUS GetStatus( PUSHORT pStatus, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID Context=NULL ); 其中,pStatus为状态值;CompletionRoutine为完成例程;pContext为传递给完成例程

Page 45: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

的环境参数。 10.7.12 复位管道函数 Reset Reset函数用于复位一个管道,Reset函数的定义格式如下: NTSTATUS Reset(void); 10.7.13 丢弃函数 Abort Abort函数用于丢弃管道上的数据传输,Abort函数的定义格式如下: NTSTATUS Abort(void); 10.7.14 初始化厂商请求函数 BuildVendorRequest BuildVendorRequest函数用于初始化一个 USB厂商请求 URB,其定义格式示例如下: PURB BuildVendorRequest( PUCHAR TransferBuffer, ULONG TransferBufferLength, UCHAR RequestTypeReservedBits, UCHAR Request, USHORT Value, BOOLEAN bIn=FALSE, BOOLEAN bShortOk=FALSE, PURB Link=NULL UCHAR Index=0, USHORT Function=URB_FUNCTION_VENDOR_DEVICE, PURB pUrb=NULL ); 其中,TransferBuffer 为数据存放缓冲区;TransferBufferLength 为传输的字节数;

RequestTypeReservedBits为 USB请求字节中的保留位;Request为请求码;Value为数值;bIn 为数据传输方向,TRUE 表示数据由设备到主机,FALSE 表示数据由主机到设备;bShortOk 为传输字节控制,为 TRUE 表示传输的字节数可以少于应指定的字节数;Link表示连接的下一个厂商请求 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.7.15 初始化类请求函数 BuildClassRequest

BuildClassRequest函数用于分配一个用于类请求的 URB,并对 USB设备进行初始化。其定义格式示例如下:

PURB BuildClassRequest( PUCHAR TransferBuffer, ULONG TransferBufferLength, UCHAR RequestTypeReservedBits,

Page 46: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

UCHAR Request, USHORT Value, BOOLEAN bIn=FALSE, BOOLEAN bShortOk=FALSE, PURB Link=NULL, UCHAR Index=0, USHORT Function=URB_FUNCTION_CLASS_DEVICE, PURB pUrb=NULL ); 其中,TransferBuffer 为数据存放缓冲区;TransferBufferLength 为传输的字节数;

RequestTypeReservedBits为 USB请求字节中的保留位;Request为请求码;Value为数值;bIn 为数据传输方向,TRUE 表示数据由设备到主机,FALSE 表示数据由主机到设备;bShortOk 为传输字节控制,为 TRUE 表示传输的字节数可以少于应指定的字节数;Link表示连接的下一个类请求 URB;Index为索引值;Function表示类别请求;pUrb表示分配一个新的 URB。

10.7.16 最大帧字节数函数MaximumPacketSize

MaximumPacketSize 函数用于读取并返回最大帧字节数,MaximumPacketSize 函数的定义格式如下:

USHORT MaximumPacketSize(void); 其典型的使用示例代码如下: USHORT size; size= MaximumPacketSize (); 10.7.17 最大传输字节数函数MaximumTransferSize MaximumTransferSize函数用于读取并返回最大传输字节数,MaximumTransferSize函

数的定义格式如下: ULONG MaximumTransferSize(void); 10.7.18 管道句柄函数 Handle Handle函数用于读取并返回管道的句柄,Handle函数的定义格式如下: USBD_PIPE_HANDLE Handle(void); 10.7.19 中断检查间隔函数 PollInterval PollInterval函数用于读取并返回中断传输的中断检查间隔,PollInterval函数的定义格

式如下: UCHAR PollInterval(void);

Page 47: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

其典型的使用示例代码如下: UCHAR pol; pol= PollInterval (); 10.7.20 管道端点地址函数 EndpointAddress EndpointAddress函数用于读取并返回管道的端点地址,EndpointAddress函数的定义格

式如下: UCHAR EndpointAddress(void); 其典型的使用示例代码如下: UCHAR add; add= EndpointAddress (); 10.7.21 设置最大传输字节数函数 SetMaximumTransferSize SetMaximumTransferSize 函 数 用 于 设 置 管 道 的 最 大 传 输 字 节 数 ,

SetMaximumTransferSize函数的定义格式如下: VOID SetMaximumTransferSize( ULONG MaxSize ); 其中,MaxSize为管道的最大传输字节数。 10.7.22 发送 URB函数 SubmitUrb SubmitUrb函数用于将 URB发送到 USB主机驱动程序中进行处理。SubmitUrb函数的

定义格式示例如下: NTSTATUS SubmitUrb( PURB pUrb, PIO_COMPLETION_ROUTINE CompletionRoutine=NULL, PVOID CompletionContext=NULL, ULONG mSecTimeOut=0 ); 其中,pUrb为创建的 URB;CompletionRoutine为完成例程;CompletionContext为传

递给完成例程的环境参数;mSecTimeOut为同步调用定时参数,以 ms为单位。 10.7.23 传输类型函数 Type

Type函数用于读取并返回管道的传输类型,Type函数的定义格式如下: USBD_PIPE_TYPE Type(void); 其典型的使用示例代码如下: USBD_PIPE_TYPE uType; uType=Type();

Page 48: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.8 USB驱动程序创建实例

采用 DriverStudio的 DriverWorks可以高效地完成 USB功能设备驱动程序的设计。这里介绍如何使用 DriverWorks的 DriverWizard进行 USB驱动程序的创建。

10.8.1 USB驱动程序建立 首先使用 DriverWorks提供的 DriverWizard工具进行 USB驱动程序框架的建立,同时

也将建立一个测试的主机应用程序,操作步骤如下: (1)在 Visual C++ 6.0中,选择“DriverStudio”→“DriverWizard”,弹出“DriverWizard”

对话框,如图 10.46所示。 (2)这里需要创建一个新的驱动程序,因此,单击“Start a New Driver Project”。此时

弹出对话框,如图 10.47 所示。在该对话框的 Project Name 中输入项目名称,例如“USBDriver”,并选择工作目录。

图 10.46 “DriverWizard”对话框

图 10.47 输入项目名称

Page 49: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

(3)单击“Next”按钮,进入下一步,如图 10.48 所示。在其中选择该项目的类型为“WDM Driver”。 (4)单击“Next”按钮,进入下一步,如图 10.49 所示。在该对话框中选择驱动程序

的类型为“WDM Function Driver”。 (5)单击“Next”按钮,进入下一步,如图 10.50 所示。在其中选择硬件接口的总线

类型为“USB”。输入该 USB设备的 VID=04B4、PID=8613。

图 10.48 选择项目的类型

图 10.49 选择驱动程序的类型

Page 50: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

(6)单击“Next”按钮,进入下一步,如图 10.51所示。其中列出了 USB的端点资源,从中可以添加删除 USB端点。 (7)单击“Add”按钮,弹出对话框,如图 10.52所示。在其中可以设置 USB端点的

参数。这里输入 Pipe Name=Pipe1、Endpoint Type=Bulk、Endpoint Address(1~15)=1、Transfer Direction=In、Maximum Packet Size=8和Maximum Transfer Size(Per URB)=4096。

图 10.50 选择 USB总线

图 10.51 USB硬件端点

(8)单击“OK”按钮,完成端点添加。同理按照图 10.53中的设置,添加 OUT端点。

Page 51: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

(9)IN端点和 OUT端点添加完毕后,如图 10.54。可以通过单击“Edit”按钮进行编辑,或者单击“Delete”按钮删除特定端点。 (10)单击“Next”按钮,进入下一步,如图 10.55所示。其中列出了主要的 IRP处理,

这里保持默认选择即可。

图 10.52 添加 IN端点 1

图 10.53 添加 OUT端点 2

图 10.54 添加的硬件端点

Page 52: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.55 IRP处理

(11)单击“Next”按钮,进入下一步,如图 10.56所示。可以按照前面的方法添加 IOCTL的自定义设置。

图 10.56 IO设置

(12)以下的步骤和前面的介绍完全一致,这里不再详细介绍,其中的设置都保持默认值即可。因此,可用单击“Finish”按钮,结束设置。 (13)此时弹出项目参数列表,如图 10.57所示。直接单击“Finish”按钮,完成 USB

驱动程序的设置。

Page 53: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

图 10.57 项目参数列表

10.8.2 USB驱动程序设计 前面建立了 USB驱动程序的框架,下面还需要根据具体的 USB设备的功能进行程序

设计。驱动程序的设计过程和前面的例子基本相似,可以使用 DeviceControl 函数实现自定义的通信接口,主要的程序设计示例代码如下:

NTSTATUS USBDriverDevice::DeviceControl(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; switch (I.IoctlCode()) //IOCTL代码 { case IOCTL_800: status = IOCTL_800_Handler(I); //IOCTL的处理 break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } if (status != STATUS_PENDING) {

Page 54: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

华清远见—嵌入式培训专家(短期高端培训、企业内训) http://www.farsight.com.cn

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

I.PnpComplete(this, status); } T.Trace(TraceInfo, __FUNCTION__"--. IRP %p, STATUS %x\n", I, status); return status; } NTSTATUS USBDriverDevice::IOCTL_800_Handler(KIrp I) { T.Trace(TraceInfo, __FUNCTION__"++. IRP %p\n", I); NTSTATUS status = STATUS_SUCCESS; ULONG inputSize = I.IoctlInputBufferSize(); //初始化 ULONG outputSize = I.IoctlOutputBufferSize(); // Buffered ioctl - using the same buffer so read the buffer before writing

the buffer PVOID inputBuffer = I.IoctlBuffer(); PVOID outputBuffer = I.IoctlBuffer(); if (FALSE) { status = STATUS_INVALID_PARAMETER; I.Information() = 0; } else { I.Information() = 0; //返回 Information } T.Trace(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP

%p, STATUS %x\n", I, status); return status; }

Page 55: 第10 章 DriverStudio 驱动程序开发工具download.hqyj.com/download/pdf/Farsight-USB10-DriverStudio.pdf · 都与Visual Studio IDE 环境集成在一起。开发人员可以在Visual

《USB应用开发技术大全》——第 10章、DriverStudio驱动程序开发工具

华清远见旗下品牌—嵌入式学院:http://www.embedu.org

10.9 小结

本章主要讲解了如何使用 DriverStudio来创建WDM驱动程序,并针对 USB设备,详细介绍了 USB设备类函数、USB接口类函数和 USB管道类函数的定义及使用。本章还通过一个实例介绍了 USB驱动程序的建立。读者应该着重掌握 DriverStudio下的 USB驱动程序的编程类函数及其使用,并能够使用 DriverStudio创建简单的 USB驱动程序。

推荐华清远见 USB相关培训课程:

嵌入式 Linux驱动开发班: http://www.farsight.com.cn/courses/TS-LinuxDriver.htm USB驱动开发高级研修班: http://www.farsight.com.cn/courses/TS-USBDriver.htm