USB接口芯片PDIUSBD12与单片机AT89C51通信系统
目录
文摘...............................................................1
英文文摘...........................................................1
1 绪论..............................................................
课题背景......................................................
课题的提出....................................................
USB简介.......................................................
主要工作......................................................
2 协议 ..........................................................
USB的互连.....................................................
USB的主机.....................................................
USB主机概述...............................................
USB驱动(USBD).............................................
设备........................................................
USB设备状态...............................................
通用USB设备操作...........................................
USB设备请求...............................................
USB的物理层...................................................
USB数据流.....................................................
3 数据采集系统的固件设计 ..............................................
固件的开发环境................................................
采用PDIUSBD12的固件设计.......................................
固件要完成的主要工作......................................
PDIUSBD12芯片特点.........................................
PDIUSBD12固件程序的编写...................................
固件的文件结构................................................
固件的编程实现................................................
底层函数..................................................
命令接口..................................................
中断服务程序.........................................
主循环..........................................
4 USB设备驱动程序设计 .................................................
Windows2000驱动程序...........................................
WDM驱动程序结构模型...........................................
USB设备驱动程序层次结构...................................
设备对象...................................................
标准总线驱动程序和类驱动程序...............................
WDM驱动程序的结构.........................................
USB驱动的开发环境.............................................
驱动的开发工具............................................
驱动开发环境的安装与设置..................................
驱动程序的实现................................................
驱动入口..................................................
数据传输控制...............................................
5 USB设备应用程序设计 .................................................
Win32 API简介.................................................
动态链接库.....................................................
MFC的应用程序开发.............................................
设备应用程序与WDM的通信........................................
Win32应用程序对WDM的通信..................................
WDM对Win32应用程序的通信..................................
应用程序的实现................................................
6 数据采集系统的硬件设计 ..............................................
硬件系统的结构................................................
接口芯片选择..................................................
6.3 接口硬件设计.................................................
A/D与单片机接口电路.......................................
PDIUSBDI2与单片机接口电路.................................
1 绪论
课题背景
随着数字化的广泛应用,数据采集也越来越重要,传统的外设与主机的通信口一般采
用ISA、PCI、C PCI、1394等标准,基于这些接口的产品,安装麻烦,价格昂贵,并受计
算机插槽数量、地址中断资源限制,且可扩展性差,USB的出现,很好地解决了以上问
题。 USB作为一种新型的串口通信标准,具有较高的传输速率,可扩展性好,采用总线供
电,使用灵活。它共有4种传输模式:控制传输、同步传输、中断传输、批量传输,以适
应不同设备的需要。
信息技术与电子技术的迅猛发展,使得计算机和外围设备也得到飞速发展和应用。过
去人们单纯追求计算机与外设之间的传输速度,现在纠错能力和操作安装的简易性也成为
人们关注的目标。USB通讯技术的出现,使高传输速度、强纠错能力、易扩展性、方便的
即插即用,有机的结合在一起。USB设备需要依据USB协议进行数据的解包与打包,底层硬
件设备与操作系统之间需要以驱动程序为桥梁。驱动程序以WDM为模型,以DDK为开发工
具,以IRP为消息传播载体,来实现与Windows系统底层核心机制相交互的功能。
课题的提出
尽管RS232是一种十分成熟且应用广泛的通讯方式,但是随着控制系统的日益复杂,
所要采集的量也会越来越多。因此寻求一种高速、安全、方便的通讯形式是十分必要
的。USB技术虽然出现的时间并不长,但是由于它的种种优点,被越来越多的厂商和用户
所接受,出现了USB打印机、摄像头等产品。尽管目前USB接口的应用主要集中在电脑的周
边外设,但是USB产品进入工控领域将是必然的趋势。采用PDIUSBD12芯片和89C51单片机
设计的基于USB总线的数据采集系统,具有可靠性高、数据不丢失、抗干扰性强、便于数
据传输和处理等优点,可在信号测试、信号采集场合广泛使用。所以本课题的研究是具有
一定的现实意义和经济意义的。
USB简介
通用串行总线(Universal Serial Bus,简称USB)是康柏、微软、IBM, DEC等公司为
了解传统总线的不足推出的一种新型串行总线接口规范, 自1995年在Comdex上亮相以来
至今己广泛地为各PC厂家所支持。现在生产的PC机几乎都配备了,USB接口,Microsoft的
windows98, NT以及MacOS, Linux, FreeBSD等流行操作系统都增加了对USB的支
持。USB的主要特点如下:
1. 速度快。 USB 有全速和低速两种方式,主模式为全速模式,速率为12Mbps,从而使一
些要求高速数据的外设,如:高速硬盘、摄像头等,都能统一到同一个总线框架下。另外
为了适应一些不需要很大吞吐量但是有很高实时性要求的设备,如鼠标、键盘、游戏杆
等,USB还提供低速方式,速率为。如表1-1所示。新推出的协议提供最高
达480Mbps的数据传输速率可以适应各种不同类型的外设。
表1-1 USB使用分类表
性能 应用 特性
低速
·交互设备
·10-20kb/s
键盘、鼠标、游戏棒 低价格、热插拔、易
用性
中速
·电话、音频、压缩视频
·500kb/s-10Mb/s
ISBN、PBX、POTS 低价格、易用性、动
态插拔、限定带宽和
延迟
高速
·音频、磁盘
·25-500Mb/s
音频、磁盘 高带宽、限定延迟、
易用性
2. 支持热插拔和即插即用。 所有的USB 设备可以随时的插入和拔离系统,USB 主机能够
动态的识别设备的状态,并自动给接入的设备分配地址和配置参数,添加、删除设备完全
不用关闭计算机,也不必像过去那样需要手动跳线和拨码开关来设置新的外设。
3. 易于扩展。USB使用的是一种易于扩展的树状结构,通过使用USB Hub扩展可连接多达
127个外设。标准USB电缆长度为3米(低速为5米)。通过Hub或中继器可以使外设距离达到
30米。
4. 使用灵活。 USB共有4种传输模式:控制传输(control),步传输(synchronization)、
中断传输(interrupt)、批量传输(bulk),适应不同设备的需要。
5. 能够采用总线供电。 普通使用串口、并口的设备都需要单独的供电系统,而USB设备
则不需要,因为USB接口提供了内置电源e USB电源能向低压设备提供最大5V, 500mA 的
电源,从而降低了这些设备的成本并提高了性价比。
6. 实现成本低。 USB对系统与PC的集成进行了优化,适合于开发低成本的外设。
本文设计的基于USB总线的数据采集系统正是充分地利用了USB 总线的上述优点,从而有
效地解决了传统数据采集系统的缺陷。很方便地就能够实现低成本、高可靠性、实时的数
据采集,适用于对瞬态信号进行采集和处理。
主要工作
本论文所设计的数据采集系统是在单片机89051控制下进行数据采集,并通过PHILIPS
公司的USB接口芯片PDIUSBDI2上传给PC机进行分析、显示和存盘。该系统用传统的USB总
线取代了RS232串行总线,通过对USB协议和设备构架的充分理解,对以单片机89C51和USB
接口芯片D12为主的数据采集系统进行了硬件设计和软件编程,并在此设计的基础上给出
相应的原理图。硬件设计主要解决的是D12与单片机的接口电路的设计。软件设计可分为
三部分:一是充分了解D12的主要功能特点,为满足D12在USB上的最大传输速率而编写固件
程序,用C51语言编写:二是在充分了解WDM驱动程序的基础上编写USB的设备驱动程序;三
是编写出界面友好、具有强大的数据处理和分析能力的应用程序。
2 协议
USB的互连
一个 USB系统主要被定义为三个部分:
·USB的互连;
·USB的设备;
·USB的主机。
USB的互连是指 USB设备与主机之间进行连接和通信的操作,主要包括以下几方面:
·总线的拓扑结构:USB设备与主机之间的各种连接方式;
·内部层次关系:根据性能叠置,USB的任务被分配到系统的每一个层次;
·数据流模式:描述了数据在系统中通过 USB从产生方到使用方的流动方式;
·USB的调度:USB提供了一个共享的连接。对可以使用的连接进行了调度以支持同步
数据传输,并且避免的优先级判别的开销。
总线拓朴结构包括四个重要的组成部分。
·主机和设备:USB系统的基础组成部分。
·物理拓朴结构:描述 USB系统中的各组成部分是如何连接起来的。
·逻辑拓朴结构:描述 USB系统中各种组成部分的地位和作用,以及描述从主机和设备
的角度观察到的 USB系统。
·客户软件层与应用层的关系:描述从客户软件层看到的应用层的情况,以及从应用层
看到的客户软件层的情况。
USB 系统中的设备与主机的连接方式采用的是星形连接,如图 2-1。
复合设备
设备设备
设备
设备
设备 设备
主机
HUB
HUB
根 HUB
图 2—1 USB物理总线的拓扑
图中的 Hub是一类特殊的 USB设备,它是一组 USB的连接点,主机中有一个被嵌入的
Hub叫根 Hub(root Hub)。主机通过根 Hub提供若干个连接点。为了防止环状连接,采用
星形连接来体现层次性,如图 4-5。这种连接的形状很像一棵树。
用于提供具体功能的设备叫应用设备。许多不同功能的设备放在一起被看作一个整
体,叫包。例如,键盘和轨迹球可以被视作一个整体,在它的内部,提供具体功能的设备
被永久地接到Hub上,而这个Hub被接到USB上。所有这些设备及这个Hub被看作一个复合设
备,而这个Hub又被看作这个复合设备的内部Hub。在主机看来,这个复合设备和一个带着
若干设备的单独Hub是一样的。图中也标出了一个复合设备。
总线逻辑拓朴结构。在物理结构上,设备通过Hub连到主机上。但在逻辑上,主机是
直接与各个逻辑设备通信的,就好像它们是直接被连到主机上一样。这个逻辑关系如图2-
2所示。与之对应的物理结构就是图2-1中的结构。Hub也是逻辑设备,但在图2-2中,为了
简化起见,未被画出,虽然USB系统中的工作都是从逻辑角度来看待的,但主机必须对物
理结构有个了解。例如,在处理Hub被移去的情况时,当一个Hub被移出,通过它与主机相
连的设备也应一起被移去,这是由其物理结构决定的。
图2-2 USB逻辑总线的拓扑
三.客户软件层与应用层的关系
USB系统的物理上、逻辑上的拓朴结构反映了总线的共享性。操纵 USB应用设备的客
户软件只关心设备上与它相关的接口,客户软件必须通过 USB软件编程接口来操纵应用设
备。这与另一些总线如 PCL,ELSA,PCMUA等不同,这些总线是直接访问内存或 I/O的。
在运行中,客户软件必须独立于 USB上的其它设备。这样,设备和客户软件的设计者就可
以只关心该设备与主机硬件的相互作用和主机软件的相互作用的细节问题。图 2-3说明了
在图 2-2的逻辑结构下,一个设备设计者看到的客户软件与相应应用的关系的视图。
图2-3客户软件和应用间的关系
逻辑设备 逻辑设
备
逻辑设
备
主机
客户软件
应用
客户软件
应用
客户软件
应用
USB的主机
USB主机概述
图 2-4展示了 USB通信模型之间基本的信息流与互连关系:
图 2-4 通信模型层次关系图
由图 2-4可见,主机与设备都被划分成不同的层次。主机上垂直的箭头是实际的信
息流。设备上对应的接口是基于不同实现的。在主机与设备之间的所有通信最终都是通过
USB的电缆进行,然而,在上层的水平层之间存在逻辑的主机-设备信息流。主机上的客
户软件和设备功能部件之间的通信是基于实际的应用需求及设备所能提供的能力。
客户软件与功能部件之间的透明通信的要求,决定主机和设备下层部件的功能以及它
们的界面(interface),图 2-5描述了从主机角度看到的它与设备的连接。
图 2-5 主机通信图
主机在整个 USB系统中是唯一的,它包括如下几个层次。
客户
USB系统
主机控制器
功能部件
USB设备
USB 总线接口
逻辑的信息流 实际的信息流
通道,代表相应层
之间连接的抽象
USB系统 硬件定义
客户(管理界面)
硬件定义
IRPS 配置信息
USB驱动器 主机软件
主机控制器驱动
主机控制器 SIE
通道组(到某一接
口)
标准通道(到缺省端口地
址)
USB电缆
·USB总线接口
·USB系统(USB System)
·USB客户(Client)
其中,USB总线接口处理电气及协议层的互连。从互连的角度看,USB设备和 USB主
机都提供类似的 USB总线接口,如串行接口引擎。由于主机在 USB系统中的特殊性,USB
主机上的总线接口还必须具备主机控制器的功能,主机控制器具有一个内集成的集线器
(根集线器)提供与 USB电缆的连接。
USB系统使用主机控制器来管理主机与 USB设备的数据传输。USB系统与主机控制器
之间的界面基于主机控制器的硬件特性。USB系统层相对于主机控制器而言,处理的是以
客户观点见到的数据传输及客户与设备的交互。这包括附加的 USB信息,比如协议
头。USB系统还必须管理 USB的系统资源,以使得客户的访问成为可能。
USB系统有三个主要组成部份:
·主机控制器驱动
·USB驱动
·主机软件
主机控制器驱动的存在,方便地将各种不同的主机控制器实现映射到 USB系统,客户
可以不必知道设备到底接在哪个主机控制器上就能同设备进行通信。USB驱动提供了基本
的面向客户的主机界面。在 HCD与 USB之间的接口称为主机控制器驱动接口(Host
Controller Driver Interface HCDI)。这层接口不能被客户直接访问,所以也不是由
USB具体来完成的。一个典型的 HCDI是由支撑各种不同主机控制器的操作系统来定义
的。
USBD提供 I/O请求包(I/O Request Packets)形式的数据传输,以某一特定通道来传
输数据。另外,USBD为它的客户提供一个容易被支配及配置的抽象的设备。作为这种抽
象的一部份,USBD拥有标准通道对设备进行一些标准的控制。这标准通道实现了 USBD与
抽象设备之间的逻辑通信。(见图 2-5)
在有些操作系统中,提供了额外的非 USB系统软件以支持设备的配置及设备驱动程序
的加载。在这样的操作系统中,设备驱动程序应使用提供的主机软件接口而不是直接访问
USBDI。
客户层描述的是直接与 USB设备进行交互所需要的软件包。当所有的设备都已连上系
统时,这些客户就可以直接通设备进行通信。一个客户不能直接访问设备的硬件。
总而言之,主机可提供如下的功能:
·检测 USB设备的连接与断开。
·管理主机与设备之间的标准控制流。
·管理主机与设备之间的数据流。
·收集状态及一些活动的统计数字。
·控制主机控制器与USB设备的电气接口,包括提供有限的能源。
USB驱动(USBD)
USBD提供了供操作系统组件特别是设备驱动程序访问设备的一组接口。这些操作系
统组件只能通过 USBD来访问 USB。USBD的具体实现基于不同的操作系统。一个 USBD可以
访问一个或多个 HCD,而一个 HCD可能与一个或多个主机控制器相连。某些操作系统可能
允许对 USBD的初始化进行一些设置。从客户的观点来看,与客户进行通信的 USBD管理着
所有连接着的 USB设备。
1. USBD概况
USBD的客户直接命令设备或从通道直接输入和输出数据流。USBD为客户提供两组工
具。命令工具和通道工具。
命令工具允许客户配置和控制 USBD操作同时配置及控制 USB设备。命令工具提供了
对设备标准通道的所有访问。
通道工具允许 USBD客户管理特定设备的数据和控制数据的传输。通道工具不允客户
直接访问设备的标准通道。
图 2-6给出了 USBD的总体框架。
图 2-6 USB 驱动结构
(1) USBD初始化
服务
通道接口
命令接口
信
息
和
流
通
道
配
置
管
理
设
备
数
据
访
问
总
线
设
备
管
理
能
量
控
制
主机控制
器驱动
主机控制
器驱动
主机控制器 主机控制器
具体的 USBD初始化工作是与操作系统有关的。当 USB系统初始化时,USB的管理信
息被创建,其中包括缺省地址设备及它的标准通道。
当一个设备连上 USB时,它响应特殊的缺省地址,直到他的唯一地址由主机给出。为
了让 USB系统能与新的设备进行通信,设备在刚连上总线时,设备的却省地址必须是可用
的。在设备的初始化期间,设备的缺省地址被修改成一个唯一的地址。
(2) USBD通道使用
通道是设备与主机的逻辑连结。一个通道由且仅由一个客户所拥有。虽然通道的基本
属性不因通道的拥有者而改变,但在两类不同客户所拥有的通道之间还存在一定的差异:
·标准通道 他们由 USBD拥有和管理。
·其他的通道 它们由 USBD的客户拥有和管理。
虽然标准通道经常用于完成一些客户通过命令接口所传递的请求,但是它们不能由客
户直接访问的。
(3) USBD服务功能
USBD提供如下种类的服务:
·通过命令工具配置设备
·通过命令工具及通道工具提供传输服务
·事件通知
·状态报告及错误恢复
2. USBD命令工具功能
USBD命令工具允许客户访问设备。通常,这些命令允许客户以读写形式访问某个设
备数据及控制部份。客户要做的仅是提供设备的标识码和相关数据缓冲区或空缓冲区指
针。
USBD命令传输时并不需要 USB设备是已被配置好。USBD提供的设备配置设施大部分
使用是用命令传输。
下面的是有关命令工具提供的功能:
(1)接口状态控制
USBD客户必须能够设置具体的接口。接口状态的改变使得所有与该接口相连的通道
都进入新的状态。另外接口的所有通道都能够被重新设置或废弃。
(2)通道状态控制
USBD通道状态由两部份组成
·主机状态。
·反映的端口状态。
通道状态值总是包含上述两部份。USBD的客户管理由 USBD报告通道状态,且客户能
够与端口交互以改变它状态。
(3)获取描述码
USBD提供取得标准设备描述符,设备配置描述符,字串描述符和设备类或者厂商定
义的描述符的功能。
(4)取得当前配置参数
USBD提供取得任何设备当前配置参数的描述符的功能。如果设备没有被配置,则不
返回描述符。当客户请求为设备设置特定的参数时也返回当前配置的描述符。返回的配置
信息中包括如下一些内容:
·所有存放在设备上的配置描述符,包括接口的所有其他可替换配置。
·返回接口的当前的配置的描述符。
·接口当前配置中的某一端口(一个接口可能具有多个端口)的通道句柄。
·接口当前配置中的某一端口的最大允许包长。
另外,对于任一通道,USBDI必须提供返回该通道的当前正使用的最大包长的值的机
制。
(5)增加设备
USBDI必须提供某种机制以便于当增加新的设备的时候,集成器驱动器能通知 USBD
并能取得该新 USB设备的 USBD标识。USBD的任务包括分配设备地址并且为设备准备使用
的标准通道。
(6)设备断开
USBDI必须提供某种机制以便于集线器控制器通知 USBD特定的设备已断开。
(7)管理状态
USBDI必须提供取得和清除设备或接口或通道上与设备有关的状态的功能。
(8)向设备发送与设备类有关的命令
USBD的客户,特别是特定类的和自适应的驱动器使用 USBD提供的该种机制向设备送
出一个或多个设备类命令。
(9)向设备发送特殊的厂商定义的命令
客户使用 USBDI提供的该种机制向设备送出一到多个厂商定义的命令。
(10)更改接口配置
USBDI必须提供更改特定接口配置的机制。修改了配置后,接口的新通道句柄替换了
旧的通道句柄。在上述的请求执行的过程中,接口必须是空闲的。
(11)创建设备配置
配置软件向 USBD提出进行设备配置的请求时提供一个包含配置信息的数据缓冲
区。USBD根据提供的配置信息为设备端口请求资源。如果所有的资源请求都得到满足,
USBD设置设备配置参数,并且返回当前设备所有活跃态接口句柄和与该接口中的某一端
口相连的通道句柄。接口的设置可使用缺省参数。
(12)设置描述符
对于支持该项行为的设备,USBDI允许升级设备上的描述符或者增加新的描述符。
3. USBD通道设施
USBD的通道设施使客户与设备之间高速的低附加信息的数据传输成为可能。数据传
输的高性能是通过将 USBD的一部份通道管理任务转交给客户来实现的。所以通道设施比
USBD命令设施所提供的数据传输服务更直接。通道设施不允许访问设备的标准通道。
只有在 USB及设备的配置都顺利完成后,客户才有可能进行 USBD的通道传输。当设
备被配置的时候 USBD根据配置参数为设备的所有通道请求资源。当特定的接口或通道空
闲的时候,客户可以更改配置。
客户为输出的通道提供一个满的数据缓冲区,并且在请求完成以后取得传输状态信
息。客户可以根据返回的状态信息判断传输是否顺利完成。
客户为输入通道提供空的数据缓冲区,并且在请求完成以后得到一个具有数据的缓冲
区及传输的状态信息。客户可根据该状态信息判断传输数据的数量及质量。根据所支持的
数据传输类型,USBD共有四种通道类型:控制传输、同步数据传输、中断传输、块传输。
USB设备
USB设备可被划分三层:
·底层是传送和接收数据包的总线接口
·中间层处理总线接口与不同端点之间的数据路由端节点是数据的终结提供处或使用
处,它可被看作数据源或数据接收端(Sink)
·最上层的功能由串行总线设备提供,比如鼠标,或 ISDN接口。
USB设备状态
USB设备有若干可能的状态,其中一些对于USB与主机(host)来说是外置的,而另外一
些对USB设备来说是内置的,表2-1描述的就是这些外置状态之间的转化关系。
表2-1外呈(可见)的设备状态
连
接
加
电
缺
省
编
址
配
置
挂
起
说 明
不 _ __ __ __ __ 设备尚未连接至接口.其他特性无关
是 不 _ _ __ __ 设备已连接至接口,但未加电. 其他特性无
关.
是 是 不 __ _ __ 设备已连接至接口,并且已加电.但尚未被
复位.
是 是 是 不 __ __ 设备已连接至接口,已加电. 并被复位.
但尚未分配地址.设备在缺省地址处可寻址.
是 是 是 是 不 _ 设备已连接至接口,已加电. 并被复位.且
分配了唯一地址.尚未被配置.
是 是 是 是 是 不 设备已连接至接口,已加电. 并被复位.且
分配了唯一地址,并被配置.设备功能可被
使用.
是 是 __ __ __ 是 设备在至少 3毫秒以内探测不到总线活动,
自动进如挂起.设备功能不可用.
通用USB设备操作
所有的USB 设备支持通用的操作集,下面简要地描述这些操
1. 动态插接与拔开
USB设备必须在任意时刻允许被插接与拔开。提供连接点或端口的集线器应当负责汇
报端口的状态改变情况。
当主机探测到连接操作后,会使得所连的集线器端口生效,设备也会因此而复位,一
个被复位了的 USB设备有如下特性:
·对缺省 USB地址发生响应
·没有被配置
·初始状态不是挂起
当设备从一个集线器端口移去时,集线器会使得原来连接的端口失效,并且通知主机
设备已移去。
2. 地址分配
当 USB设备连接以后,由主机负责给此设备分配一个唯一的地址,这个操作是在设备
复位及端口使能操作??以后。
3. 配置
USB设备在正常被使用以前,必须被配置,由主机负责配置设备。主机一般会从 USB
设备获取配置信息后再准定此设备有哪些功能。
作为配置操作的一部分,主机会设置设备的配置值,并且,如果必要的话会选择合适
的接口的备选设置。
只须一个简单配置,一个设备可能支持多重接口。一个接口是一组端结点集合,它们
代表了设备向主机提供的单一的功能或特性,用来与这组相关端结点通信的协议以及接口
内各端结点的目的可以作为一个设备类的一部分或者由厂商制定具体定义。
另外,一个配置中的结口可能有备选设置。这些备选设置会重定义相关端结点的数目
或特性。如果是这样的话,设备必须支持 GetInterface(接口请求)与 Set Interface(接
口设置)请求,来汇报及选择指定的接口的设备选设置。
4. 数据传送
数据可能以四种方式在 USB设备端结点与主机之间传送。四种传送方式参见第五章。
在不同设置下,一个终端结点可能被用于不同的传输方式,但一旦设置选定,传送方式就
选定了。
5. 电源管理
USB总线电源是一个有限的资源,在设备标识阶段,主机估测电源的需求。如果电源
的需求量超过 USB总线所能提供的电量,主机软件则不能选择那个配置。
USB设备应将电源需求量限制在一个单元以下,直到被配置。中止(挂起)的设备,不
管是否已经配置过了,应将总线耗电降到第 7章定义的标准以下。视接到设备的端口电源
负载能力而定,USB设备在配置了以后可从 VBus汲取达 5个单元的电量。远程唤醒能力
参许一个被挂起的 USB设备发达信号给处于挂起状态的主机。这个信号会使得主机醒来,
处理触发事件。USB设备通过配置描述来向主机汇报其远程唤醒的能力。USB设备的远程
唤醒能力应能被禁止的。
6. 请求处理
除 SetAddress( )请求以外,在安装完成返回 ACK信号以后,设备就开始处理请求。
在某一状态成功结束以前,设备应当“完成”对请求的处理。许多请求费时较多,像这样
的请求,该设备类应定义一个方法而不是等待交换状态信息阶段的结束来表示该操作已经
完成。像这样的操作有:集线器端口的复位至少需 10ms来完成。当端口复位产生时,
SetPortFeature(PORT-RESET)请求就结束了。当端口状态改变并表明此端口已经生效时,
一个信号就会产生表明复位信号已经结束。这种技术可以防止当主机知道某一个请求费时
较长的情况一直探测此请求是否已完成。
7. 请求错误
如果一设备收到一个请求,它或是在设备中无定义,或是不适用于当前设置,或是数
值不对,这时就会产生一个请求错误。设备在下一个数据传输阶段或状态交换阶段返回一
个表明错误的STALL PID信号,一般在下一个数据传输返回更好,这样可减少不必要的总
线活动。
USB设备请求
所有的USB设备在“设备的缺省控制通道”处对主机的请求发出响应。这些请求是通
过使用控制传输来达到的,请求及请求的参数通过Setup包发向设备,由主机负责设置
Setup包内的每个域的值。每个Setup包有8个字节。见表2-2。
表2-2 Setup数据包的格式
偏移量 域 大小 值 描述
0
bmRequest
Type
1 位图 请求特征:
D7: 传输方向
0=主机至设备
1=设备至主机
D6..5: 种类
0=标准
1=类
2=厂商
3=保留
D4..0: 接受者
0=设备
1=接口
2=端点
3=其他
4..31=保留
1 bRequest 1 值 具体请求
2 wValue 2 值 字长域,根据不
同的请求含义改
变.
4 wIndex 2 索引或
偏移
字长域,根据不
同的请求含义改
变.典型用于传送
索引或偏移.
6 wLength 2 如有数据传送阶
段,此为数据字
节数.
USB的物理层
USB的物理接口包括电气特性和机械特性。
USB通过一个四线电缆来传输信号与电源如图2-7所示。
图2-7 USB电缆定义
其中D+和D-是一对差模的信号线而VBus和GND则提供了5V的电源它可以给一些设备(包
括Hub)供电当然要有一定的条件限制。
提供了两种数据传输率一种是12Mb的高速模式,另一种是的低速模式,
这两种模式可以同时存在于一个USB系统中。而引入低速模式主要是为了降低要求不高的
设备的成本,比如鼠标、键盘等等。
USB信号线在高速模式下必须使用带有屏蔽的双绞线,而且最长不能超过5m。而在低
速模式时中可以使用不带屏蔽或不是双绞的线,但最长不能超过30m。这主要是由于信号
衰减的限制,为了提供信号电压保证以及与终端负载相匹配,在电缆的每一端都使用了不
平衡的终端负载,这种终端负载也保证了能够检测外设与端口的连接或分离,并且可以区
分高速与低速设备。
所有的设备都有上行的接口,上行和下行的接头是不能互换的,这保证了不会有非法
的连接出现。插头与插座有两个系列分别为A和B系列,A用于基本固定的外围设备,而系
列B用于经常拔插的设备,这两个系列是不能互换的。
USB 数据流
从逻辑上讲USB数据的传输是通过管道进行的。图2-6描述了USB数据传输的过程。USB
系统软件通过缺省管道(与端点0相对应)管理设备,设备驱动程序通过其它的管道来管理
设备的功能接口。实际的数据传输过程是这样的:设备驱动程序通过对USBD接口(USB
driver interface)的调用发出输入输出请求(IRP I/O Request Packet);USB驱动程序接
到请求后,调用HCD接口(host controller driver interface),将IRP转化为USB的传
输,一个IRP可以包含一个或多个USB传输;然后HCD将USB传输分解为总线操作,由主控制
器以包的形式发出。需要注意的是所有的数据传输都是由主机开始的,任何外设都无权开
始一个传输。
IRP是由操作系统定义的,而USB传输与总线操作是USB规范定义的。为了进一步说明
USB传输,我们引出帧(frame)的概念。
帧:USB总线将1ms定义为一帧,每帧以一个SOF包为起始,在这1ms里,USB进行一系
列的总线操作。引入帧的概念主要是为了支持与时间有关的总线操作。为了满足不同外设
和用户的要求,USB 提供了四种传输方式:控制传输、同步传输、中断传输、批传输。它
们在数据格式、传输方向、数据包容量限制、总线访问限制等方面有着各自不同的特征。
控制传输(Control Transfer)
1. 通常用于配置/命令/状态等情形;
2. 其中的设置操作(setup)和状态操作(status)的数据包,具有USB定义的结构,因
此控制传输只能通过消息管道进行;
3. 支持双向传输;
主机 连接 物理设备
到一个接
口的通道
束 与接口 无
缓冲 没有 USB 有关 USB格式
格式
到 0号端点的
缺省通道
USB
设备
(第
9
章)
Client SW
管理一个接口
USB System SW
管理设备
USB
USB帧格式 接口
的数据
事务
主机
控制
器
应用
接口的
集合
接口
X
USB
逻辑设备
端点的集合
端点
0
事务 USB帧格式 每个端 USB帧
的数据 点的数 结构的
据 数据
USB
主机
(第 10章)
USB线路
机械的,
通道:两个水平实体之间连接 电气的,
的抽象。
数据传递机制 被传递的数据
图 2-8 USB数据流
4. 对于高速设备允许数据包最大容量为8,16,32或64字节,对于低速设备只有8 字
节一种选择;
5. 端点不能指定总线访问的频率和占用总线的时间,USB系统软件会做出限制;
6. 具有数据传输保证,在必要时可以重试。
同步传输(Isochronous Transfer)
1. 是一种周期的连续的传输方式,通常用于与时间有密切关系的信息的传输;
2. 数据没有USB 定义的结构数据流管道;
3. 单向传输,如果一个外设需要双向传输,则必须使用另一个端点;
4. 只能用于高速设备,数据包的最大容量可以从0到1023个字节;
5. 具有带宽保证,并且保持数据传输的速率恒定,每个同步管道每帧传输一个数据
包;
6. 没有数据重发机制要求,具有一定的容错性;
7. 与中断方式一起占用总线的时间不得超过一帧的90%。
中断传输(Interrupt Transfer)
1. 用于非周期的自然发生的数据量很小的信息的传输,如键盘、鼠标等;
2. 数据没有USB 定义的结构数据流管道;
3. 只有输入这一种传输方式,即外设到主机;
4. 对于高速设备允许数据包,最大容量为小于或等于64字节,对于低速设备只能小
于或等于8字节;
5. 具有最大服务周期保证,即在规定时间内保证有一次数据传输;
6. 与同步方式一起占用总线的时间不得超过一帧的90%;
7. 具有数据传输保证,在必要时可以重试。
批传输(Bulk Transfer)
1. 用于大量的对时间没有要求的数据传输;
SIE
USB总线接口
SIE
2. 数据没有USB 定义的结构数据流管道;
3. 单向传输,如果一个外设需要双向传输,则必须使用另一个端点;
4. 只能用于高速设备,允许数据包最大容量为8,16,32或64字节;
5. 没有带宽的保证,只要有总线空闲就允许传输数据,优先级小,于控制传输;
6. 具有数据传输保证,在必要时可以重试,以保证数据的准确性。
图2-7 描述了输入输出请求IRP传输与操作之间的关系。
一个同步传送是一个
或多个 IN/OUT方向的
数据事务。
IRP
数据流类型
IRP 事务 事务 事务
所有的传送都是由一个或
多个事务组成。一个 IRP
又可由一个或多个传送组
成。
控制传送
IRP Setup
事务
数据
事务
Statu
s
事务
额外的
控制传送
控制传送首先是一个 OUT
方向的 Setup事务,然后
是多个 IN方向或 OUT方
向的数据事务,最后是一
个与数据反向的 Status
事务。
中断传送
IRP 事务 事务
一个中断传送是一个
或多个 IN/OUT方向的
数据事务。
同步传送
IRP 事务 事务 事务
批传送
事务 事务 事务
一个批传送是一个或
多个 IN/OUT方向的数
据事务。
图2-7 USB 数据传输
3 数据采集系统的固件设计
固件的开发环境
Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与
汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易
用。Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。
另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代
码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体
现高级语言的优势。
Keil C51的工具包中,uVision是C51 for Windows的集成开发环境(IDE),可以完成
编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用IDE本身或其它编辑器编
辑C或汇编源文件。然后分别由C51及A51编译器编译生成目标文件(.OBJ)。目标文件可由
LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件
(.ABS)。ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行
源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如
EPROM中。
采用PDIUSBD12的固件设计
固件编程的主要工作
固件是FIREWARE的对应中文词,它实际上是单片机的程序文件,其编写语言可以采用
C语言或是汇编语言.它的操作方式与硬件联系紧密,包括USB设备的连接USB协议、中断处
理等,它不是单纯的软件,而是软件和硬件的结合,开发者需要对端口、中断和硬件结构
非常熟悉。固件程序一般放入MCU中,当把设备连接到主机上时,上位机可以发现新设
备,然后建立连接。因此,编写固件程序的一个最主要的目的就时让Windows可以检测和
识别设备。
USB固件程序程序由三部分组成:
①初始化单片机和所有的外围电路(包括PDIUSBD12);
②主循环部分,其任务是可以中断的;
③中断服务程序,其任务是对时间敏感的,必须马上执行。
根据USB协议,任何传输都是由主机开始的。单片机作它的前台工作,等待中断。主
机首先要发令牌包给USB设备(这里是PDIUSBD12),PDIUSBD12接收到令牌包后就给单片
机发中断。单片机进入中断服务程序,首先读PDIUSBD12的中断寄存器,判断USB令牌包的
类型,然后执行相应的操作。在USB单片机程序中,要完成对各种令牌包的响应,其中比
较难处理的是SETUP包,主要是端口0的编程。
单片机与PDIUSBD12的通信主要是靠单片机给PDIUSBD12发命令和数据来实现
的。PDIUSBD12的命令字分为三种:初始化命令字、数据流命令字和通用命令
字。PDIUSBD12数据手册给出了各种命令的代码和地址。单片机先给PDIUSBD12的命令地址
发命令,根据不同命令的要求再发送或读出不同的数据。因此,可以将每种命令做成函
数,用函数实现各个命令,以后直接调用函数即可。
PDIUSBD12芯片特点
PDIUSBD12是一个性能优化的USB器件,通常用于基于微控制器的系统,并通过高速通
用并行接口与微控制器进行通信,而且支持本地DMA传输。该器件采用模块化的方法实现
一个USB接口,允许在众多可用的微控制器中选择最合适的作为系统微控制器,允许使用
现存的体系结构使固件投资减到最小。这种灵活性减少了开发时间、风险和成本。该器件
使开发成本低且高效的USB外围设备的一种有效途径。PDIUSDB12完全符合规范,也
能适应大多数设备类规范的设计,如成像类、大容量存储类、通信类、打印类和人工输入
设备等。因此,PDIUSBD12非常适合做很多外围设备。现在很多用SCSI实现的很多设备如
果用USB来实现可以直接降低成本。PDIUSBD12还集成了SoftConnect、GoodLink、可编程
时钟输出、低频晶振和终端电阻等特性。所有这些特性都能在系统实现时节省成本,同时
在外围设备上很容易实现更高级的USB功能。
PDIUSBD12固件程序的编写
USB设备启动流程如下:
1. USB设备接入USB口,发出连接USB命令;
2. 主机发出读设备描述符两次;
3. 主机根据设备描述符—厂商ID、产品ID,启动相应设备驱动程序;
4. 设备驱动程序初始化USB设备;
①读设备描述符;
②读配置描述符;
③选择接口、端点(管道),确定传输方式。
USB设备在正常使用以前,必须由主机配置设备。主机一般会从USB设备获取配置信息
后再确定此设备有哪些功能。作为配置操作的一部分,主机会设备设备的配置值,如果必
要的话会选择合适的接口备选设备。在发出连接USB命令后,主机先读取设备描述符,然
后发出设置USB地址SETUP包,设置USB地址后,进行主机客户驱动与设备初始化。其余端
点依此类推。在其头文件里需定义USB规范中的各种描述符格式,包括设备描述表、配置
描述表、接口描述表、端点描述表、字符串描述表以及描述表类型。这样,在发送配置联
合描述表时,主机USBD可以根据描述类型标识区分各种分描述表。
固件的文件结构
本数据采集系统的固件有着如下的积木式结构:
图3-1 数据采集系统固件的文件结构
固件设计的目标就是使PDIUSBD12在USB上达到最大的传输速率。外围设备可使用
PDIUSBD12 在USB上传输数据,这些设备的CPU要忙于处理许多设备控制和数据处理等任
务。PDIUSBD12 的固件设计成完全的中断驱动,当CPU处理前台任务时,USB的传输可在后
台进行,这就确保了最佳的传输速率和更好的软件结构,同时简化了编程和调试。
后台ISR中断服务程序和前台主程序循环之间的数据交换通过事件标志和数据缓冲区
主循环:发送USB请求、读入数据、控制采集通道和处
理USB总线事件等等
标准请求 厂商请求
中断服务程序
PDIUSBD12 命令接口
硬件提取层
来实现,例如PDIUSBD12的批量输出端点可使用循环的数据缓冲区,当PDIUSBD12从USB收
到一个数据包,那么就对CPU产生一个中断请求,CPU立即响应中断在ISR中固件将数据包
从PDIUSBD12内部缓冲区移到循环数据缓冲区,并在随后清零PDIUSBD12的内部缓冲区,以
使能接收新的数据包CPU可以继续它当前的前台任务直到完成然后返回到主循环检查循环
缓冲区内是否有新的数据并开始其它的前台任务。
图3-2 数据采集系统的固件结构
由于这种结构,主循环不关心数据是来自USB串口还是并口,它只检查循环缓冲区内
需要处理的新数据。这样主循环程序专注于数据的处理,而ISR能够以最大可能的速度进
行数据的传输。相似的控制端点在数据包处理时采用了同样的概念。ISR接收和保存数据
缓冲区中的控制传输并设置相应的标志寄存器。主循环向协议处理程序发出请求。由于所
有的标准器件级别和厂商请求都是在协议处理程序中进行处理,ISR得以保持它的效率。
硬件提取层:这是固件中的最底层代码,它执行对D12和硬件I/O相关访问。
PDIUSBD12命令接口:为了进一步简化PDIUSBD12的编程,固件定义了一套压
缩了所有访问PDIUSBD12功能的命令接口,以对PDIUSBD12芯片进行操作。
中断服务程序:这部分代码的处理由PDIUSBD12产生的中断,在中断服务程序
中,它将数据从PDIUSBD12的内部FIFO取回到CPU存储器并建立正确的事件标志,以通知主
循环程序进行处理。ISR通过设定事件标志“EPPFLAGS”和Setup包数据缓冲区
“CONROL_XFER”与主循环进行通信。
主循环:主循环在初始化完单片机CPU和PDIUSBD12芯片后,检查事件标
志,并进入对应的子程序进行进一步的处理,在开发套件中,它还包含人机接口的代码。
协议层和:协议层处理标准的USB器件请求和特殊的厂商请求。
固件的编程实现
底层函数
最底层为两个面向硬件电路的函数:outportb( ),inportb( ),用以完成CPU和D12之
间的数据传输,这是所有其它函数的基础。具体代码如下:
void outportb(unsigned char port, unsigned char val)
{
unsigned char xdata *ext_address;
ext_address=0xff00 + port;
*ext_address = val;
}
unsigned char inportb(unsigned char port)
{
unsigned char c;
unsigned char xdata *ext_address;
ext_address=0xff00 + port;
c = *ext_address ;
return c;
}
命令接口
在D12的数据手册中定义了一套压缩了所有访问PDIUSBD12功能的命令集,命令接口部
分就是将各命令用函数的形式加以实现。对应的函数主要有:
void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable);
//设置地址使能
void D12_SetEndpointEnable(unsigned char bEnable); //设置端点使能
void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv); //设置模式
unsigned short D12_ReadInterruptRegister(void); //读中断寄存器
unsigned char D12_SelectEndpoint(unsigned char bEndp); //选择端点
unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp); //读最后处
理状态
unsigned char D12_ReadEndpointStatus(unsigned char bEndp); //读端点状态
void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled); //
设置端点状态
void D12_SendResume(void); //发送恢复
unsigned short D12_ReadCurrentFrameNumber(void); //读取当前帧号
unsigned short D12_ReadChipID(void); //读D12芯片ID
unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char len,
unsigned char * buf);//读取端点数据
unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len,
unsigned char * buf);//写端点数据
void D12_AcknowledgeEndpoint(unsigned char endp);//设置端点应答
中断服务程序
这部分代码处理由PDIUSBDI2产生的中断,ISR从PDIUSBD12收集数据,当数据充足
时,通知主循环已经准备好等待处理。它将数据从PDIUSBDI2的内部FIFO取回到CPU存储
器,并建立正确的事件标志以通知主循环程序。在ISR函数的入口固件使用
ReadInterruptRegister()来决定中断源,根据中断源进入相应的子程序进行处理。
中断服务处理的部分代码如下:
//USB中断处理
usb_isr() interrupt 0
{
DISABLE;
fn_usb_isr();
ENABLE;
}
void fn_usb_isr()
{
unsigned int i_st;
_isr = 1;
i_st = D12_ReadInterruptRegister();
if(i_st != 0) {
if(i_st & D12_INT_BUSRESET) {
bus_reset();
_reset = 1;
}
if(i_st & D12_INT_EOT)
dma_eot();
if(i_st & D12_INT_SUSPENDCHANGE)
= 1;
if(i_st & D12_INT_ENDP0IN)
ep0_txdone();
if(i_st & D12_INT_ENDP0OUT)
ep0_rxdone();
if(i_st & D12_INT_ENDP1IN)
ep1_txdone();
if(i_st & D12_INT_ENDP1OUT)
ep1_rxdone();
if(i_st & D12_INT_ENDP2IN)
main_txdone();
if(i_st & D12_INT_ENDP2OUT)
main_rxdone();
}
_isr = 0;
}
//A/D转换中断处理
adc_isr() interrupt 1
{
DISABLE;
_isr = 1;
ENABLE;
}
主循环
主循环检查事件标志并进入对应的子程序进行进一步的处理。在主循环中,MCU首先
对其所有端口、存储区、定时器和中断服务程序进行初始化,之后MCU将重新连接USB,包
括将Softe Connect寄存器设置为ON。这些过程是很重要的,它确保了在MCU准备好服务
D12之前,D12不会进行操作。初始化后,进入循环,轮询各种状态。当轮询到了检测建立
包时,它确认建立标志在之前是否被中断服务程序所置位。如果建立标志被置位,它将向
协议层发送一个器件请求进行处理。
/* 数据采集子程序 */
void adc_handler(void)
{ unsigned char ADC_DATA;
ADC_DATA=IN_PORT;
D12_WriteEndpoint(3, 1, &ADC_DATA);
IN_PORT=0x00;
if(_rxdone) {
DISABLE;
_rxdone = 0;
ENABLE;
ADC_IN_ID =0x7FF8+GenEpBuf[3];
}
}
/* 主程序循环 */
while(TRUE){
if(_isr){ //数据采集处理
DISABLE;
_isr = 0;
ENABLE;
if()
adc_handler();
}
if (_reset) { //设备复位中断处理
DISABLE;
_reset = 0;
ENABLE;
D12SUSPD = 1;
}
if () { //挂起改变中断处理
DISABLE;
= 0;
ENABLE;
if(D12SUSPD == 1) { //挂器处理
D12SUSPD = 0;
P0 = 0xFF;
P1 = 0xFF;
P2 = 0xFF;
P3 = 0xFF;
D12SUSPD = 1;
PCON |= 0x02;
while (1);
}
}
if (_packet){ //Setup包中断处理
DISABLE;
_packet = 0;
ENABLE;
control_handler();
D12SUSPD = 1;
}
} // End Main Loop
4 USB设备驱动程序设计
设备驱动程序是一个软件组件,介于硬件与用户应用软件之间,为它们之间的通信提
供桥梁。首先必须具备编制设备驱动程序的软件环境:Visual Studio和Windows
DDK(Driver Develop Kit)。大多软件开发人员习惯于使用DriverStudio来编写设备驱动
程序,因为它产生的代码是C风格,并且由于它的封装形式类似应用程序,作为一个由应
用程序装入内核级程序编写人员,这个工具非常有用。有些却采用DDK开发方案,这样能
够避免Windows操作系统的快速更新以及其他的原因所带来的影响。
在USB的概念中,USB设备的一个类是指一组具有一些相同属性的设备的集合。把这些
设备归为一组,是为了给这一类设备开发基于HOST的驱动。这个设备类规范作为这一类设
备的框架,定义属于该类设备的操作。这让设备类驱动程序的开发可以脱离设备的制造商
而依据于规范。因此硬件制造商可以专注于它们的硬件开发,而软件开发者可以专注于开
发它们的软件和驱动程序,但所有的USB设备必须符合USB协议,一个类设备也必须符合这
个类规范要求。这个类规范说明一个USB设备和驱动程序的通讯过程。本文所讨论的基于
USB的数据采集系统,在USB中并没有定义这类设备。因为这类设备面向的应用是千差万别
的,因此这些设备很难抽象出很多的共性,因此我们需要对自己的设备开发USB的驱动程
序。
设备驱动程序主要是提供操作系统与硬件设备的接口,支持用户及其应用程序要求的
信息流。由于用户对数据快速处理的要求,驱动程序现在必须作比发送和接收数据多得多
的工作。对于该设备驱动程序的编写,我们采用WDM(Windows32 Driver Mode)驱动程序模
型,该模型主要有以下特点:①支持即插即用(PnP)和电源管理。也就是说外部设备可以在
系统运行时添加或删除,操作系统可以在任何时候分配设备需要的硬件资源,电源管理表
明设备对系统电源的使用情况是动态变化的。WDM驱动程序支持设备的电源管理,使得设
备同系统电源使用情况和设备所处的工作状态相关。②提供系统总线驱动程序。设备驱动
程序通过总线驱动程序控制在USB总线上的设备,总线驱动程序提供了一个较高层次的接
口,这个接口可以接收系统对USB设备的请求,驱动程序的功能设备对象不需要直接和USB
控制器交互信息。③支持WMI(Windows Management Instrumentation),它是一种系统管
理员报告管理信息的协议,这个协议能测量和管理消耗在本地或者是网络中客户机上的资
源信息,WDM驱动程序必须支持WMI,一般这种请求是通过IRP_MJ_SYSTEM_CONTROL请求传
递给PDO的。④支持类驱动程序/微驱动程序分层结构。WDM驱动程序采用分层结构,可和
其它驱动程序相联系,接收建立在其上的驱动程序提供的服务,也可向其它驱动程序发送
IRP请求。WDM型驱动程序采用了分层处理的方法,用户不需要直接和硬件打交道,而只需
要通过下层驱动程序提供的接口来访问硬件。
微软在他们的WinHEC96中发布了Win32驱动程序模型WDM。它的目标是为Windows NT,
Windows9x和以后的产品提供一个通用的驱动程序框架。在Windows操作系统中提供了对
USB很好的支持。WDM存在于Windows NT的驱动程序模型基础之上,并增加了对即插即用和
电源管理的支持,Windows2000系列操作系统也是建立在NT构架上的。因此一个在Windows
2000下开发出来的WDM驱动程序,也可以在其它的Windows环境下运行。
Windows2000驱动程序
我们的USB设备的HOST驱动程序是在Windows2000下开发的WDM驱动程序。在讲述USB的
客户驱动开发之前,先看一下关于Win2000驱动程序和WDM程序模型。图4-1是Windows2000
的设备驱动程序类型框图。
图4-1 Windows2000驱动程序类型框图
虚拟设备驱动程序是一个用户态的组件,一个基于DOS的应用程序可以通过它处理X86
虚拟设备驱动程序 内核态驱动程序
文件系统驱动程序 驱动程序 PnP驱动程序 显示驱动程序
WDM驱动程序
类驱动程序 微驱动程序
计算机上的硬件。VDD(Virtual device driver)依靠I/O允许屏蔽位来控制端口操作,它
必须仿真硬件操作,以方便那些在一个裸机上,直接对硬件操作的应用程序。内核态驱动
程序这个分支包含了很多子分支,其中PnP驱动程序用来管理Windows2000的即插即用协
议;一个WDM驱动程序是添加了电源管理协议,并且在Windows98和Windows2000中相兼容
的一类PnP驱动程序。在WDM驱动程序中,有很多不同的类驱动程序,类驱动程序管理一类
定义好的设备。而微驱动程序提供了厂商关于某类设备的特定驱动;显示驱动程序是对显
示和打印的内核驱动,它们的主要特征是显示可视化数据;文件系统驱动程序在本地硬盘
或者网络上实现标准的PC文件系统模型(它包括一个层次结构的目录和文件名);遗留设备
驱动程序是一类可以直接控制硬件设备而不需要其它驱动程序介入的内核驱动程序,它主
要包括那些在Windows NT的以前版本中开发的,现在仍在Windows2000中运行的驱动程
序。
WDM驱动程序结构模型
Windows 32模式驱动程序模型可以在Windows 98, Windows ME, Windows2000下使
用。WDM是Microsoft全力推出的新驱动程序模式,目的是提供一种灵活的方式简化驱动程
序开发,实现对新硬件的即插即用,减少并降低驱动程序开发的数量和复杂性。WDM驱动
程序可以看作是在Windows 驱动程序基础上发展起来的驱动程序模型,它和NT驱动
程序有很多相似的地方,这两种类型的驱动程序都采用层次结构,能处理系统发出的IRP
请求,IRP结构基本相同,操作系统中为支持NT驱动程序提供的服务也适合于WDM驱动程
序。但是WDM驱动程序提供了许多支持新硬件设备的结构。
USB设备驱动程序层次结构
WDM重新定义了驱动程序的分层,以适应即插即用,各个不同层次的驱动程序构成了
设备的驱动程序栈。如图4-2所示。WDM驱动模型中每个硬件至少有两个驱动程序。一个是
功能驱动程序,即通常硬件设备的驱动程序,负责初始化1/O操作,处理UO操作完成时带
来的中断,提供设备适合的控制方式。另一个是总线驱动程序,负责管理硬件与计算机的
连接。同时还存在各种类型的过滤驱动程序,它是一个中间层的驱动程序,可以截获并处
理经过它的I/O请求,变更标准设备驱动程序的行为,但不重写总线驱动程序或类驱动程
序,仅修改感兴趣的动作,过滤驱动程序是相对于一个特定的驱动程序层而存在并帮其完
成一些辅助功能。
上层类过滤驱动程序
上层设备过滤驱动程序
功能驱动程序
低层类过滤驱动程序
低层设备过滤驱动程序
总线过滤驱动程序
过滤驱动程序
图4-2 设备驱动程序栈
设备对象
WDM中驱动程序和设备对象的层次关系如图4-3所示。图的左侧是一个设备对象的堆
栈,设备对象是系统创建的一种数据结构,软件通过它来管理硬件。对一个物理上的硬件
来说,可以对应很多的设备对象。堆栈中最底层的设备对象称为物理设备对象(PDO,
physical device object),堆栈中间底称为功能设备对象(FDO,functional device
object),在FDO的上下存在一些过滤设备对象的驱动程序,在FDO之上的称之为上层过滤
设备对象,在FDO之下,PDO之上的称之为下层过滤设备对象。功能驱动程序是驱动程序完
成控制设备操作功能最主要的部分,这个层位于总线驱动程序上面。驱动程序在功能驱动
程序层创建一个功能设备对象,放在驱动程序设备栈中,在这个功能驱动程序分层之上,
还可能会有多个功能驱动程序分层,以完成相应任务。
总线驱动程序控制对总线上所有设备的访问。如果想要访问USB设备,必须使用USB
总线驱动程序。总线驱动程序负责枚举它的总线,即发现总线上的全部设备和检测设备何
时被添加和删除。总线创建一个PDO代表它发现的设备。一些总线驱动程序简单控制对总
线的访问,一旦有了控制权,就可以对总线做任何想做的事情。
图4-3 WDM中设备对象和驱动程序层次结构
在其它情况下,总线驱动程序为我们处理总线上的所有事务。功能驱动程序知道如何
控制设备的主要功能,它分层在总线驱动程序的上面。功能设备驱动程序创建一个FDO,
放在设备栈中。在USB情况下,功能驱动程序必须使用USB类驱动程序访问它的设备。但在
其余情况下,一旦总线驱动程序接管,功能驱动程序可以直接访问硬件。各种类型的过滤
驱动程序可以插在设备栈内。对总线上的所有设备,下层过滤驱动程序被加在总线驱动程
序之上;对一个特定类的所有功能驱动程序,上层过滤驱动程序被添加在功能驱动程序之
IRP
FDO 上层过滤驱动程序
功能设备驱动程序
下层过滤驱动程序
总线驱动程序
FDO
FDO
FDO
上。任何用户请求总是从设备栈的顶部进入的。假设用户程序标识了一个它想访问的功能
设备,UO管理器保证它的全部请求被发送到设备栈的顶部,这样任何高层的过滤驱动程序
或功能驱动程序就得到首先处理这些请求的机会。
标准总线驱动程序和类驱动程序
Windows系统提供了许多标准总线驱动程序和类驱动程序,作为系统中总线驱动程序
和功能驱动程序的通用驱动程序。通常,标准驱动程序和支持实际硬件设备接口的另一个
驱动程序或另一类驱动程序一起使用来操作实际硬件设备。这些辅助的另一个驱动程序或
另一类驱动程序通常称为小类驱动程序或者是小端口驱动程序。系统提供的标准总线驱动
程序和类驱动程序,有以下几类:
1. 人工输入设备(HID)类驱动程序。HID类驱动程序提供了输入设备一个抽象视图,
实际输入硬件可以使用不同的方法和系统链接,这些具体链接方法通过HID类驱动程序实
现。
2. USB总线驱动程序。USB总线驱动程序可以枚举和控制低速USB总线,USB客户驱动
程序使用各种IOCTL通过USB类驱动程序来访问它们的硬件设备。
3. 静态图像体系结构。确切地说,静态图像体系结构不是驰动程序,而是使用小驱
动程序获得扫描仪和静态图像的一种手段,STI目前支持SCSI设备、串行设备、并行设备
和USB设备。
4. 流类驱动程序。这类驱动程序提供了访问高带宽、时间关键的视频音频数据基
础,通过流类小驱动程序的使用,可以接到实际硬件。
5. 端口类驱动程序。使用端口类,可以很容易地将硬件不同部分表示成不同的子设
备,音频端口类驱动程序使COM标志这些子设备,子设备和小端口驱动程序用于控制实际
硬件。
6. IEEE1394总线驱动程序。IEEE1394总线驱动程序枚举和控制IEEF1394的高速总
线,这个总线驱动程序使用端口驱动程序访问IEEE1394控制电路。
7. SCSI类驰动程序和CDROM/DVD类驱动程序。SCSI和CDROM/DVD驱动程序用于访问硬
盘、软盘、光盘和DVD.
8. ACPI总线驱动程序。ACPI是高级配置和电源接口总线驱动程序,它和PCACPI BIOS
打交道,枚举系统中的设备并控制这些设备的功率使用。
9. PCI总线驱动程序。PCI是外设组件互联总线驱动程序,用来枚举和配置PCI总线上
的设备。
10. PnPISA总线驱动程序。PnPISA总线驱动程序,对可以使用即插即用配置的工业标
准体系结构ISA设备作枚举和配置。
WDM驱动程序的结构
WDM驱动程序采用入口点模型,驱动程序由驱动程序入口点和一系列分发例程组成。
在NT驱动程序中入口点函数为DriverEntry(),此函数完成驱动程序的一切初始化驱动工
作和设备所需要的资源信息,为每个查找到的设备创建设备对象,通过驱动程序对象输出
分派函数入口点。而在WDM驱动程序模型中,在其入口点方面,主要增加了两个重要的入
口点:一个是AddDeviceU入口点,指向这个入口点的指针存放在DriverObject->
DriverExtension->AddDevice()里。另一个是处理即插即用IRP_MJ_PNP输入/输出请求包
的分派入口点,指向这个分派入口点的指针应该存放在DriverObject->
MajorFunction[IRP_MJ_PNP]里。在WDM驱动程序中,以前在NT驱动程序入口点函数
DriverEntry()中完成的功能,被分为三个不同的部分,由不同的入口点来完成。①同初
始化驱动程序自身相关的工作。这些工作,如输出入口点等仍然在DriverEntry()中完
成。②同查找驱动程序支持的设备相关的工作。这些工作包括创建设备对象等,在驱动程
序入口点AddDevice()中执行。③同设备资源和设备初始化相关的工作。同设备硬件自身
相关的工作,实际上要等到调用IRP_MJ_PNP输入/输出请求包和微函数
IRP_MJ_START_DEVICE时,才会进行处理。对于这部分工作,只是将其简单地连接到中断
服务例程中去处理。
WDM驱动程序按其功能可分为以下几个模块:(1)初始化驱动程序自己。(2)创建和删除
设备。(3)处理Windows32打开和关闭文件句柄的请求。(4)处理Windows32输入/输出请
求。(5)串行化对设备的访问。(6)访问硬件。(7)调用其它驱动程序。(8)取消I/O请求。
(9)超时I/O请求。(10)处理一个可热拔插的设备被加入或者删除的情况。(11)使用电源管
理请求。(12)使用WMI和NT事件向系统管理员报告。
驱动程序装入的实现
在刚开始PnP就有一个对“根总线”的内嵌“驱动程序”,这个“根总线”实际并不
存在,它在概念上包括所有的连到计算机上但不能通过电子的方式表明自己存在的硬件一
包括最初的硬件总线(如PCI总线)。根总线驱动程序从系统的安装过程中取得信息,系统
安全程序通过检测硬件并询问用户相应的信息,从而得到关于这个计算机的信息。因此,
根总线驱动程序有足够的信息可以创建主总线的PDO。
主总线的功能驱动程序这时可以枚举它们自己的硬件。如PCI总线,它对每一个连到
总线上的设备保留一个特殊的配置空间,这个配置空间包括了对设备的描述和对资源的需
求。当总线驱动程序枚举硬件时,它好像是一个普通的功能驱动程序,一旦检测到一个硬
件,驱动程序就转换了角色:它变成了一个总线驱动程序并为这个硬件创建了一个PDO,
PnP管理器为这个设备的PDO装入驱动程序。也可能功能设备驱动程序枚举到多个硬件,这
时上述过程递归调用。此时总线设备驱动程序堆栈分支成其它的设备驱动程序堆栈,这些
堆栈对应于连接到这个总线上的硬件。
Windows使用驱动程序枚举可用的硬件,枚举是指查找并列出任何可用的设备,然后
使用仲裁器调整所有的资源请求。对每个设备查找合适的驱动程序,然后告诉这些驱动程
序使用哪些资源,并运行这些驱动程序。例如,枚举从最低层开始,PC中的根设备查找主
板上的基本芯片。它查找任何简单的设备,如内置的串行口和键盘,它还查找PCI适配器
(控制PCI总线的电路)。然后,PCI总线驱动程序枚举和配置它所发现的所有硬件。首先,
它发现到ISA总线的桥,它的驱动程序然后发现一个PnP ISA声卡,并装入该声卡的驱动程
序。PCI总线驱动程序不像其他的硬件驱动程序通过硬件抽象层(HAL)访问它的硬件,USB
的驱动程序依赖于它的总线驱动程序()。为了发送一个请求给设备,驱动程序要
创建一个USB请求包(URB,USB request block),并将它发送给USB总线驱动程序。例如为
了配置一个USB设备,驱动程序需要递交几个URB,以读取配置和发送命令。根据
命令和总线带宽调度这些请求,并将它们发送到总线上。
根据USB协议的规定,每一个USB设备都可以有一个或多个配置,它们控制着设备的行
为。设备的每一种配置可以包含一个或多个接口,这个接口描述软件操作硬件的方式。对
于支持相同接口的设备,它们的软件是可以互相替换的,因为相同的接口规定了相同的命
令和方法。同时,接口也有一个可选设置,以适应不同带宽的需要。每一个设备的接口可
以有很多的端点,每一个端点代表着一个管道。Windows提供了几个系统驱动程序,用其
支持USB总线。它们包括了一个主机控制器的驱动(
驱动(),一个被控制器驱动所用的类驱动程序()。由于我们的客户端
驱动程序主要和打交道,所以可以把以上的所有驱动统一用来表示。因
此我们所要做的USB驱动程序就是根据系统方案和USB协议,构筑不同的URB,并将其通过
内部IOCTL的方式,发送给USB的总线驱动程序()。
图4-4 USB的WDM接口框图
USB驱动的开发环境
驱动的开发工具
本设计采用Visual C++、Win DDK 2600和 DriverStudio 作为开发基于USB的
数据采集系统驱动程序的软件开发环境。其中DriverStudio为主要开发工
具。DriverStudio是设备驱动程序开发工具中的极品 。这套革新的软件包括久经考验的
工具SoftICE、DriverWorks、VtoolsD和DriverAgent,以及基于应用层技术的新的设备驱
动程序工具。目前又最新推出了针对网络驱动程序开发的工具DriverNetworks。这就构成
了一整套工具软件,它们加快了设备驱动程序的开发、调试、测试、调谐以及部
署。DriverStudio把高质量的工具和现代的软件工程实践带给了一度被忽视的设备驱动程
序编程领域。
由于采用了即插即用、电源管理和新的WDM驱动程序体系结构等技术,开发和测试哪
怕最简单的设备驱动程序也变得比任何时候都复杂。DriverStudio采用新的WDM类、即插
即用消息的缺省处理,以及可以揭示Windows 2000内核真实运行状况的全面追踪功能。这
就使Windows 2000驱动程序的开发工作,从设计到部署,都得到了简化。DriverStudio提
供的视窗系统设备驱动程序开发工具可以提高开发速度,改善测试方法,增强可靠性。不
管你的专业技术水平如何,不管你处于哪个开发阶段,也不管你现在选用的是什么工具,
DriverStudio都会使你在开发设备驱动程序时感到更轻松。DriverStudio中的
DriverWorks工具为开发Windows NT、Windows 2000和Windows 98 WDM设备驱动程序提供
了一个自动化的方法,这个产品包括改进的DriverWizard。DriverWorks提供独特的
DriverWizard可以自动生成代码,可以引导开发人员完成设备驱动程序开发的全过程,并
能根据你的硬件种类自动生成设备驱动程序源代码。类库把常用的操作封装起来,大大减
少了你的编码工作。精心制作的类库减少了对简单接口的复杂操作,而且在模仿基本操作
系统的面向对象特性时,甚至比微软的DDK所提供的程序性基于C语言的接口做得更好。
驱动开发环境的安装与设置
开发驱动程序之前,先要安装和设置开发环境。安装开发软件时必须按照先装Visual
C++,再装Win DDK 2600,最后装DriverStudio 的顺序进行。三个软件最好都选
择完全安装,可以避免发生找不到文件或类库之类的错误,安装DDK时可以去除对应64位
操作系统的选项。安装完成后还需要进行一些设置,首先需要设置DDK的开发环境,在开
始菜单中找到并点击Checked Win XP DDK Build EnvelopMents,在窗口中键入build –
cZ,开始执行批处理,会自动设置环境并创建所需类库和文件。然后就需要编
译DriverWorks中的类库。在Visual C++ 中选择菜单 File|Open Workspace,打开位于C:
\Program files\ DriverStudio\ DriverWorks\Source\的工作空间文件,选
择菜单 Build|Batch Build,在弹出的对话框中选择x86系列的库,点击Build编译选择的
库,点击Rebuild重新编译一次类库。点击开始菜单中Compuware DriverStudio\Develop\
DDK Build Settings设置并进入组合开发环境,到此就完成了驱动开发环境整个设置。
驱动程序的实现
USB设备驱动程序在本设计中由四个模块实现:初始化模块、即插即用管理模块、电
源管理模块以及I/O功能实现模块。初始化模块提供一个入口函数DriverEntry(),所有对
各种IRP(I/O Request Packet,IRP请求包)的处理例程都在此入口函数中做出定义。即插
即用管理模块实现USB设备的热拔插及动态配置。当硬件检测到USB设备接入时,
Windows98查找响应的驱动程序,并调用它的DriverEntry例程,PnP管理器调用驱动程序
的AddDevice例程,告诉它添加了一个设备;在此处理过程中,驱动程序收到一个设备启
动请求(IRP_MN_START_DEVICE)的IRP。同理,当要拔除时,PnP管理器会发出一个设备删
除请求(IRP_MN_REMOVE_DEVICE)的IRP,由驱动程序进行处理。通过对这些PnP请求的处
理,可支持设备的热插拔和即插即用功能。电源管理模块负责设备的挂起与唤醒。
I/O功能实现模块完成I/O请求的大部分工作。若应用程序想对设备进行I/O操作,它
便使用Windows API函数,对WIN32子系统进行WIN32调用。此调用由I/O系统服务接收并通
知I/O管理器,I/O管理器将此请求构造成一个合适的I/O请求包(IRP)并把它传递给USB设
备驱动程序,USB设备驱动程序接收到这个IRP以后,根据IRP中包含的具体操作代码,构
造相应的USB请求块并把此URB放到一个新的IRP中,然后把此IRP传递到USB总线驱动程
序,USB总线驱动程序根据IRP中所含的URB执行相应的操作(如从USB设备读取数据等),并
把操作结果通过IRP返还给USB设备驱动程序。USB设备驱动程序接收到此IRP后,将操作结
果通过IRP返还给I/O管理器,最后I/O管理器将此IRP中操作结果返还给应用程序,至此应
用程序对USB设备的一次I/O操作完成。
驱动入口
USB驱动程序和一般的DOS/Windows C语言程序不一样,它没有main()或者WinMain()
函数入口。和DLL类似地,它向操作系统显露一个名称为DriverEntry()的函数,在启动驱
动程序的时候,操作系统将调用这个入口。DriverEntry除了做一些必要的设备初始化工
作外,还初始化一些Dispatch例程入口。我们知道,USB应用和设备驱动程序打交道主要
是通过CreateFile、ReadFile、WriteFile和DeviceIoControl等Win32 API来进行的。这
些API其实都对应着驱动程序的一些Dispatch例程。而驱动程序除了DriverEntry以外,主
要就是由这些Dispatch例程组成的。例如调用Win32 API CreateFile的时候,操作系统最
终转化为对驱动程序IRP_MJ_CREATE功能代码所对应的Dispatch例程的调用,如果驱动程
序没有提供该例程,CreateFile调用就会失败。
驱动程序入口的代码如下:
NTSTATUS DataCollectDriver::DriverEntry(PUNICODE_STRING RegistryPath)
{
(TraceInfo, __FUNCTION__"++. Compiled at " __TIME__ " on " __DATE__
"\n");
#ifdef DBG
//DbgBreakPoint();
#endif
NTSTATUS status = STATUS_SUCCESS;
m_Unit = 0;
UNREFERENCED_PARAMETER(RegistryPath);
(TraceInfo, __FUNCTION__"--. STATUS %x\n", status);
return status;
}
数据传输控制
本数据采集系统有八个数据采集通道,所以需要对数据采集通道进行控制,以便于选
取合适通道和进行通道的切换,这些任务就由IOCTL_ChannelControl_Handler(KIrp I)函
数完成。采集后的数据通过USB总线传送的计算机的指定缓冲区中,以便于调用和进行处
理,所以用IOCTL_GetData_Handler(KIrp I)函数从USB设备获取数据,并将所得数据传递
给应用程序。IOCTL_GetData_Handler(KIrp I)和IOCTL_GetData_Handler(KIrp I)函数代
码如下:
NTSTATUS DataCollectDevice::IOCTL_ChannelControl_Handler(KIrp I)
{
(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = ();
ULONG outputSize = ();
PVOID inputBuffer = ();
PVOID outputBuffer = ();
// TODO: Validate the parameters of the IRP.
if (FALSE)
{
status = STATUS_INVALID_PARAMETER;
() = 0;
}
else
{
// TODO: copy data
() = 0;
}
(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP
%p, STATUS %x\n", I, status);
return status;
}
NTSTATUS DataCollectDevice::IOCTL_GetData_Handler(KIrp I)
{
(TraceInfo, __FUNCTION__"++. IRP %p\n", I);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputSize = ();
ULONG outputSize = ();
PVOID inputBuffer = ();
PVOID outputBuffer = ();
// TODO: Validate the parameters of the IRP.
if (FALSE)
{
status = STATUS_INVALID_PARAMETER;
() = 0;
}
else
{
// TODO: copy data
() = 0;
}
(NT_SUCCESS(status)?TraceInfo:TraceWarning, __FUNCTION__"--. IRP
%p, STATUS %x\n", I, status);
return status;
}
5 USB设备应用程序设计
USB设备应用程序是实现PC机对USB接口芯片PDIUSBD12的接口控制和读写操作,提供
友好的人机界面。由于应用程序中涉及到与硬件打交道的底层函数,会大量的引用Win32
API函数,在Visual C++环境下开发是比较直观和顺乎逻辑的。要编写USB设备的驱动程
序,必须要有能够编译WDM驱动程序的软件环境,建议使用Visual C++来编制该驱动程
序。应用程序主要通过对驱动程序中函数的利用来实现对USB设备的操作控制。因此在编
写设备应用程序时,可以使用可读性和移植性很好的Visual C++,Visual Basic,Delphi
等开发环境来生成控制所需的交互界面,大大方便用户使用。
设计USB设备应用程序时:一个是使用MFC(Microsoft Foundation Class),这样工作
量相对来说要少得多,用户也比较方便;另一个是使用底层的API函数编写程序,这样虽
然比较繁琐,但是可以使编程人员看到许多使用MFC编程时看不到的东西,也能够深入了
解Windows系统更底层的知识。
Win32 API简介
Windows API(Application Programming Interface)即基于Windows的应用程序编程
接口,由Windows下基本的系统函数调用组成,专门为Windows下的编程提供支持。就高级
编程语言来说,Windows API是Windows环境下底层函数的调用,所有在Win32平台上运行
的应用程序都可以调用这些函数。Microsoft的所有32位平台都支持统一的API,包括函
数、结构、消息、宏和接口。既然位于底层,完全使用API编程便显得十分繁琐,事倍功
半。但是利用底层的函数可以使程序员了解Windows的内部,知道Windows程序的来龙去
脉。使用Win32 API,应用程序能充分挖掘Windows系统的潜力,不但可以开发出在各种平
台上都能运行的应用程序,而且可以充分利用每个平台特有的功能和属性。标准的Win32
API函数可以分为以下几类:窗口管理、图形设备接口、系统服务、窗口通用控件、Shell
特性、国际特性和网络服务。
1.窗口管理函数:窗口管理函数提供了建立和管理用户界面的方法。用窗口管理函数
可以建立窗口、通过窗口来显示输出、提示用户输入以及完成其他一些与用户进行交互所
需要的操作。
2.图形设备接口:图形设备接口提供了一系列函数的相关结构,可用来在显示器、打
印机或其他设备上生成图形化的输出结果。用GDI函数可以绘制直线、曲线、闭合图形、
文本以及位图图像。所绘制的图形颜色和风格依赖于所建立的绘图对象,即画笔、刷子和
字体。可以用画笔绘制直线和曲线,用刷子来填充闭合图形的内部,用字体来书写文本。
3.系统服务:系统服务函数提供了访问计算机资源以及底层操作系统特性的手段,例
如访问内存、文件系统、设备、进程和线程。使用系统服务函数,应用程序可以管理和监
视所需要的资源。例如,可以用内存管理函数来分配和释放内存,用进程管理和同步函数
来启动和调整多个应用程序或在一个应用程序中运行的多个线程的操作。
4,其他函数:Win32 API中有一些接口和函数,可用来增强系统Shell的功能。Shell
用一个单层结构的名字空间来组织用户关心的所有对象,包括文件、存储设备、打印机及
网络资源;通用控件是由通用控件库支持的一个控件窗口集,作为ActiveX
控件直接使用通用控件:国际特性函数有助于编写国际化的应用程序;网络服务函数主要
用于网络的操作,包括网络上不同计算机应用程序之间的通信,在网络上各计算机建立和
管理共享资源的链接等。
动态链接库
由于Windows属于多任务操作系统。在多任务环境中,应用程序共享内存资源,如果
多个应用程序都调用库文件中相同的函数,则在链接时把该函数拷贝给每个应用程序,运
行时在内存中生成同一个函数的多个拷贝,造成内存资源的浪费。此外,如果修改了库中
函数的代码,则必须对调用该函数的应用程序重新进行链接。因此在Windows环境下,通
常不使用静态链接方式,而使用动态链接库,即DLL(Dynamic Link Library)。动态链接
库是一个函数库,由可被其它程序或DLL调用的函数集合组成的可执行文件模块,之所以
称为动态链接库,是因为DLL的代码并不是某个应用程序的组成部分,而是在运行时链接
到应用程序中。与动态链接不同,静态链接方式是在链接期间把静态链接库中的代码链接
到可执行文件中,也就是说,在可执行文件中含有库函数的代码。动态链接分为两个阶段
一链接过程和装入过程。当应用程序调用动态链接库中的某个函数时,链接程序并不拷贝
被调用函数的代码,而只是从引入库中拷贝一些指示信息,指出被调用函数属于哪个动态
链接库。因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中该
函数的内存地址。程序运行后,当需要调用该函数时,进入装入过程,把应用程序与DLL
库一起装入内存,由Windows读入DLL中的函数并运行程序。可以看出,动态链接是在应用
程序被装入到内存时进行的。这样当多个应用程序调用库中的同一个函数时,不会在内存
中有该函数的多个拷贝,而是只有一份拷贝,每个应用程序的可执行文件中装入的只是该
函数的内存地址,程序运行时再把应用程序代码与被调函数代码动态链接起来,从而可以
节省内存资源。同时,由于DLL与应用程序分开,即使更新DLL,也不用修改已经编译好的
可执行文件。
动态链接库还存在一些缺点,在运行应用程序时,Windows必须将应用程序所需要的
函数从动态链接库中调出来,如果使用静态链接,则在生成EXE文件时就将所需要的函数
放入应用程序中,在装入应用程序时,这些函数即同时被装入。此外,整个动态链接库须
随着相应的EXE文件一起走,即使只是用到其中的一小部分也必须完成这个过程。
MFC的应用程序开发
友好的可视化用户界面非常便于用户操作使用,但是却增加了设计人员的负担。几乎
所有的开发平台都可以设计可视化的程序,可是如果其操作系统没有提供基本的应用程序
开发接口,那么设计可视化程序的工作就很繁琐了,在面向对象兴起后,应用程序框架也
应运而生。MFC只是其中之一,他不但是个很大的类库,还将类之间的关系很密切的结合
起来。MFC把Windows API包装起来,建立了一些很容易使用和理解的函数,还将其中的一
部分隐藏起来,只在链接时加入以降低工程的规模。另外,微软基础类库还介绍了
Document和View的机制,让数据处理与显示的部分区分的很清楚。
设备应用程序与WDM的通信
设备应用程序与WDM是双向通信的,下面分别介绍,以便更好的理解设备应用程序对
USB设备的控制操作。
Win32应用程序对WDM的通信
Win32应用程序在Windows中调用WDM的Win32函数共有五个:CreateFile(),
ReadFile(),WriteFile(),DeviceloControl()和CloseHandle()。这些函数的执行都对
应着驱动程序的一些例程。下面就其中的一些编程问题作一些说明:
1. 打开一个WDM 设备。应用程序打开一个WDM 设备驱动程序,用的是CreateFile()
函数。它的第一个参数是一个符号链接名。一旦应用程序获得设备的有效句柄,它就能够
调用Win32函数,这将产生对应于此设备对象的相应IRP。
2. 关闭一个WDM设备。WDM允许多个应用程序打开同一个设备,它为每个应用程序创
建一个设备对象。当其中的一个应用程序调用CloseHandle()函数,驱动程序首先收到
“清除”IRP,驱动程序应当在“清除”例程中清除和此设备对象有关的待处理的IRP。然
后收到“关闭”IRP,关闭设备对象。
3. ReadFile()和WriteFile()函数的调用。特征标志位DO_BUFFERED_IO决定着WDM驱
动程序该如何访问应用程序调用ReadFileo和WriteFile()函数的数据缓冲区。I/0管理器
根据设备对象的此特征标志位,决定着ReadFile()和WriteFileo函数的缓冲器参数在一个
IRP中的表示法。
4. DeviceloControl()函数的调用。对于DeviceIoControl()函数的调用,驱动程序
根据I/O控制命令来决定该如何获取应用程序的缓冲器地址。I/O控制命令中的数据访问方
式的定义有METHOD BUFFERED, METHOD IN DIRECT,METHOD OUT DIRECT 或METHOD NEIT
HER。如果控制命令定义为METHOD BUFFERED,系统分配一个缓冲区用于输入和输出,该缓
冲区的字节数为应用程序的输入和输出缓冲区的大者的字节数。驱动程序必须先拷贝输入
数据,然后再复制输出数据。驱动程序通过KIrp::IoctIBufer获得缓冲区的地址。对于输
出,驱动程序将必须把存储字节数赋给(),完成后,I/O管理器将数据从
系统缓冲区复制到应用程序的数据缓冲区。
WDM对Win32应用程序的通信
应用程序创建一个事件后,可直接将事件句柄传递给WDM,然后等待WDM发送事件消
息。WDM驱动程序获取这个事件的一个对象指针后,只能在DISPATCH LEVEL级别的例程中
设置事件信号状态。此外,WDM还提供了其他两种对Win32应用程序通信的方式。一种方式
是创建一个命名的事件;另一种方式是当应用程序调用DeviceloControl()函数时,WDM返
回STATUS_ENDING。当一个事件发生后,WDM完成这个IRP调用DeviceloControl()函数的线
程接着往下执行,处理发生的事件。
应用程序的实现
用户应用程序是系统与用户的接口,它通过通用驱动程序完成对外设的控制和通信。
在编程时,首先要建立与外设的连接,然后才能实施数据的传输。用户程序首先必须查找
设备,打开设备的句柄,然后进行读写和控制操作,最后是关闭设备句柄。用户应用程序
的流程如图5-1所示。
NN
Y
Y
成功
失败
检测 USB设备
设置设备参数
启动 A/D模块
请求上传数据包 报告数据丢失
获得有效数据包 下组数据准备就绪
显示错误信息返回
存储、显示数据
延迟至下组数据包准备就绪
启动 USB设备
图5-1 应用程序流程图
用户应用程序的主要功能为:开启或关闭USB设备、检测USB设备、设置USB数据传输
管道、设置A/D状态和数据采集端口、实时从USB接口采集数据、显示并分析数据。当
PDIUSBD12的FIFO缓冲区存满后,PDIUSBD12自动将数据打包即时请求读入数据,由SIE自
动发送数据包。另外,当系统启动A/D模块后,便会创建两个线程:采样线程和显示存盘
线程。采样线程负责将采集数据写到应用程序提交的内存;而显示存盘线程负责给应用程
序发送显示和存盘消息。当应用程序接收到此消息后,便从它提交的内存中读取数据并显
示和存盘。此处需要注意的是采样线程和显示存盘线程在读写应用程序提交的内存时要保
持同步。
数据的显示及数据采集的控制都需要由应用程序的人机交互界面来完成,本设计的应
用程序界面如图5-2所示,包括对USB设备的打开与关闭、数据采集的开始与停止及采集端
图5-2 应用程序的界面
口的控制,具体功能由程序内部代码实现。数据采集应用设计中用于数据采集端口选择以
及采集数据获取的部分函数片段如下:
VOID DataCollectIOCTL_ChannelControlCompleteCallback(PVOID Context)
{
PDATACOLLECT_LIST_ITEM ioItem = (PDATACOLLECT_LIST_ITEM)Context;
DataCollectOutputText(
_T("Executed IOCTL_ChannelControl request: in buffer size (%d), out
buffer size (%d), return length (%d) error (%d)"),
ioItem->InSize,
ioItem->OutSize,
ioItem->ReturnLength,
ioItem->Error
);
// Dump the output buffer
DataCollectOutputBuffer(ioItem->OutBuffer, ioItem->ReturnLength);
// Free our buffer memory
free(ioItem->InBuffer);
free(ioItem->OutBuffer);
// Close our overlapped event handle
CloseHandle(ioItem->);
// Free our ioItem memory
free(ioItem);
return;
}
VOID DataCollectIOCTL_GetDataCompleteCallback(PVOID Context)
{
PDATACOLLECT_LIST_ITEM ioItem = (PDATACOLLECT_LIST_ITEM)Context;
DataCollectOutputText(
_T("Executed IOCTL_GetData request: in buffer size (%d), out buffer
size (%d), return length (%d) error (%d)"),
ioItem->InSize,
ioItem->OutSize,
ioItem->ReturnLength,
ioItem->Error
);
// Dump the output buffer
DataCollectOutputBuffer(ioItem->OutBuffer, ioItem->ReturnLength);
// Free our buffer memory
free(ioItem->InBuffer);
free(ioItem->OutBuffer);
// Close our overlapped event handle
CloseHandle(ioItem->);
// Free our ioItem memory
free(ioItem);
return;
}
6 数据采集系统的硬件设计
硬件系统的结构
基于 USB总线的实时数据采集系统硬件组成包括模拟开关、A/D转换器、单片机、USB
接口芯片,该系统能够实现 8路数据自动采集,系统的组成框图如图 6-1所示。主要包括
5个组成部分:中央处理器选用 AT89C51芯片,完成各部分控制功能和 USB传输协议;A/D
转换器和接口电路主要完成数据采集,并读入 MCU处理;复位电路完成对 MCU的上电复位
和电源电压监视;电源电路主要为各部分提供要求的电源;外设与主机间的通信电路采用
USB接口。单片机通过8位并行接口传送经过 A/D转换的采集数据,存储在 FIFO存储器
中。一旦存满,串行接口引擎 SIE立刻对数据进行处理,包括同步模式识别、并/串转
换、位填充/不填充、CRC校验、PID确认、地址识别以及握手鉴定,处理完毕后数据由模
拟收/发器通过 D+、D-发送至 PC。上述过程遵循 协议。
图 6-1 数据采集系统硬件组成框图
6.2 接口芯片选择
PDIUSBD12是一款性价比很高的USB器件,它通常用作微控制器系统中实现与微控制器
进行通信的高速通用并行接口。它还支持本地的DMA传输。
这种实现USB接口的标准组件使得设计者可以在各种不同类型微控制器中选择出最合适的
微控制器。这种灵活性减小了开发的时间风险以及费用(通过使用已有的结构和减少固件
上的投资),从而用最快捷的方法实现最经济的USB外设的解决方案。
PDIUSBD12完全符合版的规范,它还符合大多数器件的分类规格:成像类、海
量存储器件、通信器件、打印设备以及人机接口设备。同样地,PDIUSBD12理想地适用于
许多外设,例如:打印机、扫描仪、外部的存储设备、Zip驱动器和数码相机等等,它使
得当前使用SCSI的系统可以立即降低成本。
PDIUSBD12 所具有的低挂起功耗连同LazyClock输出可以满足使用ACPI、OnNOW和USB电源
管理的要求。低的操作功耗可以应用于使用总线供电的外设。
此外它还集成了许多特性包括SoftConnetTM、GoodLinkTM、可编程时钟输出、低频晶
振和终止寄存器。集合所有这些特性都为系统显著节约了成本,同时使USB功能在外设上
的应用变得容易。
D12芯片的主要特点包括:
·符合 版本规范;
·可与任何外部微控制器/微处理器实现高速并行接口(2MB/s);
·采用 GoodLink技术的连接指示器,在通信时使 LED闪烁;
·主端点的双缓冲配置增加了数据吞吐量并轻松实现实时数据传输;
·在批量和等时模式下均可实现 1Mb/s的数据传输率;
·完全自治的直接内存存取 DMA操作。
PDIUSBD12内部结构如图 6-2所示。
多
路
模
拟
开
关
A
/
D
转
换
器
MC
U
US
B
接
口
芯
片
PC
机
控
制
器
图 6-2 PDIUSBD12内部结构
6.3 接口硬件设计
由 D12接口组成的通信电路原理如图 6-3所示。多路地址/数据总线 ALE接单片机的
ALE脚,这样使用传送指令可以与 D12接口,对 D12操作就象对 D12操作一样,此时忽略
A0(命令口和数据口地址线)的输入。因为没有使用 DMA传输方式,所以没有用到 DMACK_
N、EOT_N和 DMREQ_N等 DMA引脚。INT_N是 USB中断请求脚,发出 USB中断请求;GL_N
是 GooDLink指示灯,在调试过程中非常有用,在通信时会不停闪烁。如果一直亮或者一
直暗,表示 USB接口有问题,如果 D12挂起,则 LED关闭。CLKOUT是 D12的时钟输出,可
以通过固件编程改变其频率,在调试固件时,可作为参考。
A/D与单片机接口电路
ADC0809允许的最大时钟频率为1280kHz,主要管脚功能如下:
INO-IN7: 8路模拟量输入端,可从这8个脚输入OV-5V待转换的模拟电压。
ADDA,ADDB,ADDC: 管道地址输入端。通过编码的方式来实现管道地址的选择。
CLOCK: 时钟输入端。ADC0809只有在时钟脉冲信号的同步下才能进行A/D转换时钟频
率越高转换得越快。典型时钟频率是640kHz.
ALE: 地址锁存允许端。
START: 启动脉冲输入端。在时钟脉冲频率为640kHz时,START脉宽应大于100ns-
200ns 。
EOC: 转换结束信号端。在A/D转换期间,EOC=O表示转换正在进行,输出数据不可
信,转换完毕后立即使EOC=1表示转换己经完成,输出数据可信。
D7-DO: 转换所得八位输出数据,D7是最高位,而DO是最低位。
OE: 允许输出端。OE端控制输出锁存器的三态门。当OE=1时,转换所得数据出现在
D7-DO脚,当OE=0时D7-DO脚对外是高阻抗。
图6-4 ADC0809与89051的接口电路
89C52通过和读、写控制线来控制转换器的模拟输入通道地址锁存、启动
和允许输出。编程时注意启动AD0809后,EOC在一定时间才能变成低电平。
PDIUSBDI2与单片机接口电路
PDIUSBDI2与89C52的连接电路如图6-5所示。89C52的ALE和PD 12的ALE相接,表示采
用单独地址和数据总线配置。其AO脚接高电平用于控制命令或数据输入到PDIUSBDI2,也
就是编程中outportcmd()和outportdata()函数。此外89052的多位地址/数据复用总线PO
可直接与PDIUSBD12的数据总线相连,CLKOUT时钟输出为89C52提供时钟输入。
图6-5 PDIUSBD12与89C51的连接电路
在该数据采集系统中,用ADC0809采集0-5V的电压信号,经A/D转换后将数字量存入预
先设定的缓冲区里,利用接口芯片D12将数据送至USB总线上。设备应用程序从缓冲区里取
数据显示,通过数值来说明USB接口的采集速率比一般的串行总线速度高。当前端的电压
信号不断变化的同时,在PC上可以观察到数据的变化,这就表明利用USB接口在数字采集
系统中进行数据传输是能够实现的,而且能够很好的实现。
7 结论
USB是一种IT行业新发展起来的通用接口标准,目前很多应用主要集中在PC机的外设
和一些消费类电子上。其实,作为一种通用型串行总线标准,USB不仅仅适用于IT行业,
它的应用空间很广泛,完全可以使用在不同的领域和行业。特别是由于USB的使用简单、
即插即用、热插拔、开放性、高速、稳定、可靠性高等优点,它特别适用于仪器仪表、虚
拟仪器、数据采集、数据采集设备、监控设备和加密设备等等场合。
本论文所完成的工作和分析可概括为以下几点:
1. 对规范进行了较为详细的研究。分析了USB主机、USB设备、USB物理层以及USB
连接,详细说明了USB的数据流。
2. 详细地介绍了PHILIPS公司PDIUSBD12接口器件和使用Keil c51开发固件。探索了
PDIUSBD12固件编程的思想,将PDIUSBD12的固件设计成完全的中断驱动,MCU有更多
的时间处理其它工作。
3. 论述了WDM设备驱动程序模型以及开发USB设备驱动程序的方法。分析了USB设备驱动程
序的层次结构以及各层次的功能,构造出USB设备驱动程序的框架。详细说明了驱动
开发环境的设置,介绍了用DriverSudio如何开发USB驱动程序。
4. 详细地介绍了Windows API及设备应用程序与WDM的通信。说明了应用程序的工作流
程,给出了应用程序的操作界面。
5. 我们使用的是标准,存在许多不足。最大传输率可以达到12Mbps,是指主机控
制器最大的处理能力,而一个USB设备不可能拥有这么高的带宽,它的带宽由主机的
总线驱动程序管理。当添加或者删除一个USB设备时,连接的其它USB设备的资源要重
新分配,以提高总线的利用率。单个USB设备所能拥有的带宽一般小于8Mbps。为了实
现高速数据传输,应该考虑使用标准。
6. 由于开发板使用AT89C51作为D12的控制器,这就从根本上限制了数据传输速度的提
高。它的工作主频比较低,晶振太小,处理数据不够迅速。可以使用速度更快的处理
器。
7. 在对应用程序进行MFC编程时,思维和算法不够慎密,在考虑内存管理方面不够完善。
8. 开发板中的固件编程使用了C51编写,虽然程序的可读性相对较好,但它的执行效率却
不如汇编语言的执行效率高。因此,选择编程语言也是提高设备传输率的方法之一。
9. 使用DriverSudio开发USB驱动程序十分方便,但环境设置较为复杂,特别是
DriverSudio和DDK之间以及它们与系统之间存在兼容问题,这很容易使初学者陷入困
境。
虽然本设计还有许多缺陷,不足以完成大批量数据的高速传送,但是它己经是USB数
据采集系统的雏形。只要在后续的研究中通过改善硬件环境和软件算法解决好一系列存在
的问题,一定会得到充分体现USB总线简单易用、传输速度快等特点的数据采集系统。
综上所述,本论文己经完成了基于USB的数据采集系统的所有开发步骤,从设备的硬
件到固件,到主机系统的驱动程序接口,再到用户应用程序。相信随着USB总线技术的发
展,它的应用前景会更加广阔。
参考文献
[1] 陈启美,丁传锁编著.计算机USB接口设计[M].南京:南京大学出版社,
[2] 尹勇,王洪成编著.单片机开发环境μVision 2的使用指南及USB固件编程与调试[M].
北京:北京航空航天大学出版社,
[3]李全利,迟荣强编著.单片机原理及接口技术[M].北京:高等教育出版社,
[4]周立功编著.PDIUSBDI2 USB固件编程与驱动开发[M].北京:北京航空航天大学出版社,
[5]边海龙,贾少华编著.设备的设计与开发[M].北京:人民邮电出版社,
[6]张弘编著.USB接口设计[M].西安:西安电子科技大学出版社,
[7]坎特编著.Windows WDM设备驱动程序开发指南[M].孙义,马莉波等译.北京:机械工业
出版社,
[8]刘炳文,李凤华编著Visual Basic Win32 API程序设计[M].北京:清华大学出版
社,
[9]张惠娟,周利华,瞿鸿鸣编著.Windows环境下的设备驱动程序设计[M].西安:西安电子
科技大学出版社,
[10]齐舒创作室编著.Visual C++开发技巧及实例剖析[M].北京:清华大学出版社,
[11] Compaq, Intel, Microsoft, Serial Bus Specification
[S].1998
[12] Philips, DataSheet[EB]. 2000