Windows 下 usb 接口芯片的驱动技术
一、 USB 概述
USB 的英文全称为 Universal Serial Bus, 中文含义是通用串行总线,是由 Conpaq 、 DEC 、 IBM 、 Inter 、 Microsoft 、 NEC 和 Northen Telecom 等公司为简化 PC 与外设之间的互连而共同研究开发的一种免费的标准化连接器,它支持各种 PC 与外设之间的连接,还可实现数字多媒体集成。现在生产的 PC 几乎都配备了 USB 接口, Microsoft 的 Windows98 、 NT 以及 MacOS 、 Linux 、 FreeBSD 等流行操作系统都增加了对 USB 的支持。它是一种快速的,双向的,同步传输的廉价的并可以进行热拔插的串行接口。 USB 接口使用方便,它可以连接多个不同的设备,而过去的串口和并口只能接一个设备。速度快是 USB 技术的突出特点之一。全速 USB 接口的最高传输率可达 12Mb/s, 比串口快了整整 100 倍, USB 总线标准由 1.1 版升级到 2.0 版后,传输率由 12Mbps 增加到了 480Mbps , . 这使得高分辨率、真彩色的大容量图象的实时传送成为可能。 USB 接口支持多个不同设备的串列连接,一个 USB 接口理论上可以连接 127 个 USB 设备。连接方式也十分灵活,既可以使用串行连接,也可以使用集线器 (Hub) 把多个设备连接在一起,再同 PC 机的 USB 接口相接。普通的使用串口、并口的设备都需要单独的供电系统,而 USB 设备则不需要。正是由于 USB 的这些特点,使其获得了广泛的应用。
二、 USB 的总线结构
USB 的 总线 结构是采用阶梯式星形( tiered star )的拓扑( topology )结构,如上图和下图所示。每一个星形的中心是 集线器 ,而每一个设备可以通过集线器上的 接口 来加以连接。从图中可以看到 USB 的设各包含了两种类型: USB 集线器与 USB 设备。位于最顶端的就是 Host (主机端)。从 Host 的联机往下连接至 Hub (集线器),再由集线器按阶梯式以一层或一阶的方式往下扩展出去,连接在下一层的设备或另一个集线器上。事实上,集线器也可视为一种设备。而其中最大层数为 6 层(包括计算机内部的根集线器)。每一个星形的外接点的数目可加以变化,一般集线器具有 2 、 4 或 7 个接口。
在此的主机端通常是指 PC 主机。当然,主机端因具有根集线器,因此也含有集线器的功能。而集线器是在 USB 规范中特别定义出来的外围设备,除了扩增系统的连接点外,还负责中继( repeat )上端/下端的信号以及控制各个下端端口的 电源 管理。至于另一个设备,即是用户常见的外围设备。但在 USB 规范书中,称这种设备为 “ 功能 ” ( functi on s ),意味着此系统提供了某些 “ 能力 ” ,例如具有键盘或鼠标等功能。当然不同的外围设各可以具有不同的功能。通过这种阶梯式星形的连接方式,最多可同时连接到 127 个设备。
三、 USB 结构与工作原理
一个 USB 系统可以从三个方面加以描述:
(1)USB 互联。
(2)USB 设备。
(3)USB 主机。
USB 互联是指一个 USB 设备与 USB 主机相联并和其通信的方式 , 它包括:
(1) 总线拓扑结构: USB 主机和 USB 设备的连接模型。
(2) 层间关系: USB 在系统中的每一层都要完成一定的任务。
(3) 数据流模型: USB 系统中信源和信息之间的数据传送方式。
(4) 任务规划: USB 提供可以共享的互联机制。通过规划对互连机制的访问,可以支持同步数据传输。
四、 USB 硬件结构
一个 USB 系统包含三类硬件设备 : USB 主机 (USB HOST) 、 USB 设备 (USB DEVICE) 、 USB 集线器 (USB HUB) 。
(1)USB HOST
在一个 USB 系统中,当且仅当有一个 USB HOST 时, USB HOST 有以下功能 :
Ø 管理 USB 系统 ;
Ø 每毫秒产生一帧数据 ;
Ø 发送配置请求对 USB 设备进行配置操作 ;
Ø 对总线上的错误进行管理和恢复。
(2)USB DEVICE
在一个 USB 系统中, USB DEVICE 和 USB HUB 总数不能超过 127 个。 USB DEVICE 接收 USB 总线上的所有数据包,通过数据包的地址域来判断是不是发给自己的数据包:若地址不符,则简单地丢弃该数据包 ; 若地址相符,则通过响应 USB HOST 的数据包与 USB HOST 进行数据传输。
(3)USB HUB
USB HUB 用于设备扩展连接,所有 USB DEVICE 都连接在 USB HUB 的端口上。一个 USB HOST 总与一个根 HUB (USB ROOT HUB) 相连。 USB HUB 为其每个端口提供 100mA 电流供设备使用。同时, USB HUB 可以通过端口的电气变化诊断出设备的插拔操作,并通过响应 USB HOST 的数据包把端口状态汇报给 USB HOST 。一般来说, USB 设备与 USB HUB 间的连线长度不超过 5m , USB 系统的级联不能超过 6 级 ( 包括 ROOT HUB) 。
USB 总线最多可支持 127 个 USB 外设连接到计算机系统。 USB 的拓扑是树形结构,有 1 个 USB 根集线器 (root hub) ,下面还可有若干集线器。 1 个集线器下面可接若干 USB 接口。 USB 线缆包括 4 条线: Vbus(USB 电源 ) 、 D+( 数据 ) 、 D-( 数据 ) 和 Gnd(USB 地 ) 。线缆最大长度不超过 5m 。 USB1.1 的传输速率最高为 12Mb/s( 低速外设的标准速率为 1.5Mb/s ,高速外设的标准速率为 12Mb/s) 。 USB 外设可以采用计算机里的电源 (+5V , 500mA) ,也可外接 USB 电源。在所有的 USB 信道之间动态地分配带宽是 USB 总线的特征之一,这大大地提高了 USB 带宽的利用率。当一台 USB 外设长时间 (3ms 以上 ) 不使用时,就处于挂起状态,这时只消耗 0.5mA 电流。按 USB1.0/1.1 标准, USB 的标准脉冲时钟频率为 12MHz ,而其总线时脉冲时钟为 1ms(1kHz) ,即每隔 1ms , USB 器件应为 USB 线缆产生 1 个时钟脉冲序列。这个脉冲系列称为帧开始数据包 (SOF) 。高速外设长度为每帧 12000bit( 位 ) ,而低速外设长度只有每帧 1500bit 。 1 个 USB 数据包可包含 0~1023 字节数据。每个数据包的传送都以 1 个同步字段开始。
五、 USB 的数据流
主控制器负责主机和 USB 设备间数据流的传输。这些传输数据被当作连续的比特流。每个设备提供了一个或多个可以与客户程序通信的接口,每个接口由 0 个或多个管道组成,它们分别独立地在客户程序和设备的特定终端间传输数据。 USBD 为主机软件的现实需求建立了接口和管道,当提出配置请求时,主控制器根据主机软件提供的参数提供服务。
USB 支持四种基本的数据传输模式:控制传输,等时传输,中断传输及数据块传输。每种传输模式应用到具有相同名字的终端,则具有不同的性质。
控制传输类型:支持外设与主机之间的控制,状态,配置等信息的传输,为外设与主机之间提供一个控制通道。每种外设都支持控制传输类型,这样主机与外设之间就可以传送配置和命令 / 状态信息。等时传输类型:支持有周期性,有限的时延和带宽且数据传输速率不变的外设与主机间的数据传输。该类型无差错校验,故不能保证正确的数据传输,支持像计算机 - 电话集成系统 (CTI) 和音频系统与主机的数据传输。
中断传输类型:支持像游戏手柄,鼠标和键盘等输入设备,这些设备与主机间数据传输量小,无周期性,但对响应时间敏感,要求马上响应。
数据块传输类型:支持打印机,扫描仪,数码相机等外设,这些外设与主机间传输的数据量大, USB 在满足带宽的情况下才进行该类型的数据传输。
USB 采用分块带宽分配方案,若外设超过当前带宽分配或潜在的要求 , 则不能进入该设备。同步和中断传输类型的终端保留带宽,并保证数据按一定的速率传送。集中和控制终端按可用的最佳带宽来传输传输数据。
六、 USB 外设控制器的两种实现方式
USB 芯片在外设领域的应用面很广。 USB 外设控制芯片通常包括 USB 收发器、串行接口引擎 (SIE) 、 USB 控制器和外设功能等四个模块 (SIE 主要以硬件方式处理大多数 USB 协议, USB 控制器负责与 PC 交互通信信息 ) 。 USB 控制器一般有两种类型:一种是 MCU 集成在芯片里面的,如 Intel 的 8X930AX 、 CYPRESS 的 EZ-USB 、 SIEMENS 的 C541U 以及 MOTOLORA 、 National Semiconductors 等公司的产品 ; 另一种就是纯粹的 USB 接口芯片,仅处理 USB 通信,如 PHILIPS 的 PDIUSBD11(I2C 接口 ) 、 PDIUSBP11A 、 PDIUSBD12( 并行接口 ) , National Semiconductor 的 USBN9602 、 USBN9603 、 USBN9* 等。
集成 MCU 的 USB 控制芯片优点是 CPU 与控制器在同一片芯片里, CPU 只需要访问一系列寄存器和存储器,便可实现 USB 口的数据传输,最大限度的发挥 USB 高速的特点。而且简化了程序的设计,极大地降低了 USB 外设的开发难度。缺点是灵活性不够高,开发成本较大。
纯粹的 USB 接口芯片的优点是系统组成灵活,可根据不同的系统需求,搭配不同的 MCU ,具有较高的性能价格比。但因为 USB 控制器是通过串行口或并行口与 MCU 连接,在传输速度方面和开发难度方面不如集成了 MCU 的控制芯片。
不同的实现方式在设计开销、上市时间、 元器件 开销和引脚数方面各有优劣,选择不同的方案意味着在以上各项指标中进行取舍。如 PHILIPS 公司的 PDIUSBD12 器件。该芯片是一款性价比很高的 USB 器件,它通常用作 微控制器 系统中实现与微控制器进行通信的高速通用并行接口,设计者可根据需要选择合适的微控制器,灵活性较大,适用于开发低成本且高效的 USB 外围设备。
七、 USB 设备的枚举过程
USB 架构中, hub 负责检测设备的连接和断开,利用其中断 IN 端点 (Interrupt IN Endpoint) 来向主机( Host )报告。在系统启动时,主机轮询它的根 hub ( Root Hub )的状态看是否有设备(包括子 hub 和子 hub 上的设备)连接。
一旦获悉有新设备连接上来,主机就会发送一系列的请求 (Resqusts) 给设备所挂载到的 hub ,再由 hub 建立起一条连接主机( Host )和设备( Device )之间的通信通道。然后主机以控制传输 (Control Transfer) 的方式,通过端点 0(Endpoint 0) 对设备发送各种请求,设备收到主机发来的请求后回复相应的信息,进行枚举( Enumerate )操作。所有的 USB 设备必须支持标准请求( Standard Requests ),控制传输方式( Control Transfer )和端点 0 ( Endpoint 0 )。
当枚举完成后,这个新添加的设备可在 Windows 的设备管理器里面看到,当用户删除这个设备 / 硬件时,系统把这个设备从设备管理器里删除。
对于一般的设备,固件( Firmware )内包含主机所要请求的信息,而有些设备则是完全由硬件来负责响应主机的请求。在主机方面则是由操作系统而非应用程序负责处理相关枚举操作。
枚举步骤
USB 协议定义了设备的 6 种状态,仅在枚举过程种,设备就经历了 4 个状态 的迁移:上电状态 (Powered) ,默认状态 (Default) ,地址状态 (Address) 和配置状态 (Configured) (其他两种是连接状态和挂起状态( Suspend ))。
USB 协议定义了设备的 6 种状态,仅在枚举过程种,设备就经历了 4 个状态的迁移:上电状态 (Powered) ,默认状态 (Default) ,地址状态 (Address) 和配置状态 (Configured) (其他两种是连接状态和挂起状态( Suspend ))。
下面步骤是 Windows 系统下典型的枚举过程,但是固件不能依此就认为所有的枚举操作都是按照这样一个流程行进。设备必须在任何时候都能正确处理所有的主机请求。
1. 用户把 USB 设备插入 USB 端口或给系统启动时设备上电。
这里指的 USB 端口指的是主机下的根 hub 或主机下行端口上的 hub 端口。 Hub 给端口供电,连接着的设备处于上电状态。
2.Hub 监测它各个端口数据线上 (D+/D-) 的电压
在 hub 端,数据线 D+ 和 D- 都有一个阻值在 14.25k 到 24.8k 的下拉电阻 Rpd ,而在设备端, D+ (全速,高速)和 D- (低速)上有一个 1.5k 的上拉电阻 Rpu 。当设备插入到 hub 端口时,有上拉电阻的一根数据线被拉高到幅值的 90% 的电压(大致是 3V )。 hub 检测到它的一根数据线是高电平,就认为是有设备插入,并能根据是 D+ 还是 D- 被拉高来判断到底是什么设备(全速 / 低速)插入端口(全速、高速设备的区分在我将来的文章中描述)。如下图。
检测到设备后, hub 继续给设备供电,但并不急于与设备进行 USB 传输。
3. Host 了解连接的设备。
每个 hub 利用它自己的中断端点向主机报告它的各个端口的状态(对于这个过程,设备是看不到的,也不必关心),报告的内容只是 hub 端口的设备连接/断开的事件。如果有连接/断开事件发生,那么 host 会发送一个 Get_Port_Status 请求 (request) 以了解更多 hub 上的信息。 Get_Port_Status 等请求属于所有 hub 都要求支持的 hub 类标准请求( standard hub-classrequests )。
4.Hub 检测所插入的设备是高速还是低速设备。
hub 通过检测 USB 总线空闲 (Idle) 时差分线的高低电压来判断所连接设备的速度类型,当 host 发来 Get_Port_Status 请求时, hub 就可以将此设备的速度类型信息回复给 host 。( USB 2.0 规范要求速度检测要先于复位( Reset )操作)。
5.hub 复位设备。
当主机获悉一个新的设备后,主机控制器就向 hub 发出一个 Set_Port_Feature 请求让 hub 复位其管理的端口。 hub 通过驱动数据线到复位状态 (D+ 和 D- 全为低电平 ) ,并持续至少 10ms 。当然, hub 不会把这样的复位信号发送给其他已有设备连接的端口,所以其他连在该 hub 上的设备自然看不到复位信号,不受影响。
6.Host 检测所连接的全速设备是否是支持高速模式。
因为根据 USB 2.0 协议,高速( High Speed )设备在初始时是默认全速( Full Speed )状态运行,所以对于一个支持 USB 2.0 的高速 hub ,当它发现它的端口连接的是一个全速设备时,会进行高速检测,看看目前这个设备是否还支持高速传输,如果是,那就切到高速信号模式,否则就一直在全速状态下工作。
同样的,从设备的角度来看,如果是一个高速设备,在刚连接 bub 或上电时只能用全速信号模式运行(根据 USB 2.0 协议,高速设备必须向下兼容 USB 1.1 的全速模式)。随后 hub 会进行高速检测,之后这个设备才会切换到告诉模式下工作。假如所连接的 hub 不支持 USB 2.0 ,即不是高速 hub ,不能进行高速检测,设备将一直以全速工作。
7. Hub 建立设备和主机之间的信息通道。
主机不停得向 hub 发送 Get_Port_Status 请求,以查询设备是否复位成功。 Hub 返回的报告信息中有专门的一位用来标志设备的复位状态。
当 hub 撤销了复位信号,设备就处于默认/空闲状态( Default state ),准备着主机发来的请求。设备和主机之间的通信通过控制传输,默认地址 0 ,端点号 0 进行。在此时,设备能从总线上得到的最大电流是 100mA 。
8. 主机发送 Get_Descriptor 请求获取默认管道的最大包长度。
默认管道( Default Pipe )在设备一端来看就是端点 0 。主机此时发送的请求是默认地址 0 ,端点 0 ,虽然所有位分配地址的设备都是通过地址 0 来获取主机发来的信息,但由于枚举过程不是多个设备并行处理,而是一次枚举一个设备的方式进行,所以不会发生多个设备同时响应主机发来的请求。
设备描述符的第 8 字节代表设备端点 0 的最大包大小。对于 Windows 系统来说, Get_Descriptor 请求中的 wLength 一项都会设为 64 ,虽然说设备所返回的设备描述符( Device Descriptor )长度只有 18 字节,但系统也不在乎,此时,描述符的长度信息对它来说是最重要的,其他的瞄一眼就过了。 Windows 系统还有个怪癖,当完成第一次的控制传输后,也就是完成控制传输的状态阶段,系统会要求 hub 对设备进行再一次的复位操作( USB 规范里面可没这要求)。再次复位的目的是使设备进入一个确定的状态。
9. 主机给设备分配一个地址。
主机控制器通过 Set_Address 请求向设备分配一个唯一的地址。在完成这次传输之后,设备进入地址状态( Address state ),之后就启用新地址继续与主机通信。这个地址对于设备来说是终生制的,设备在,地址在;设备消失(被拔出,复位,系统重启),地址被收回。同一个设备当再次被枚举后得到的地址不一定是上次那个了。
10. 主机获取设备的信息。
主机发送 Get_Descriptor 请求到新地址读取设备描述符,这次主机发送 Get_Descriptor 请求可算是诚心,它会认真解析设备描述符的内容。设备描述符内信息包括端点 0 的最大包长度,设备所支持的配置( Configuration )个数,设备类型, VID ( Vendor ID ,由 USB-IF 分配), PID ( Product ID ,由厂商自己定制)等信息。 Get_Descriptor 请求 (Device type) 和设备描述符(已抹去 VID , PID 等信息) 之后主机发送 Get_Descriptor 请求,读取配置描述符( Configuration Descriptor ),字符串等,逐一了解设备更详细的信息。事实上,对于配置描述符的标准请求中,有时 wLength 一项会大于实际配置描述符的长度( 9 字节),比如 255 。这样的效果便是:主机发送了一个 Get_Descriptor_Configuration 的请求,设备会把接口描述符,端点描述符等后续描述符一并回给主机,主机则根据描述符头部的标志判断送上来的具体是何种描述符。
11. 主机给设备挂载驱动(复合设备除外)。
主机通过解析描述符后对设备有了足够的了解,会选择一个最合适的驱动给设备。在驱动的选择过程中, Windows 系统会和系统 inf 文件里的厂商 ID ,产品 ID ,有时甚至用到设备返回来的产品版本号进行匹配。如果没有匹配的选项, Windows 会根据设备返回来的类,子类,协议值信息选择。如果该设备以前在系统上成功枚举过,操作系统会根据以前记录的登记信息而非 inf 文件挂载驱动。当操作系统给设备指定了驱动之后,就由驱动来负责对设备的访问。对于复合设备,通常应该是不同的接口( Interface )配置给不同的驱动,因此,需要等到当设备被配置并把接口使能后才可以把驱动挂载上去。
设备 - 配置 - 接口 - 端点关系见下图:
实际情况没有上述关系复杂。一般来说,一个设备就一个配置,一个接口,如果设备是多功能符合设备,则有多个接口。端点一般都有好几个,比如 Mass Storage 设备一般就有两个端点(控制端点 0 除外)。
12. 设备驱动选择一个配置。
驱动(注意,这里是驱动,之后的事情都是有驱动来接管负责与设备的通信)根据前面设备回复的信息,发送 Set_Configuration 请求来正式确定选择设备的哪个配置( Configuration )作为工作配置(对于大多数设备来说,一般只有一个配置被定义)。至此,设备处于配置状态,当然,设备也应该使能它的各个接口( Interface )。
对于复合设备,主机会在这个时候根据设备接口信息,给它们挂载驱动。
13. 设备可使用。
至此,步骤完成,设备可用了。