PDF全文下载地址:http://download.csdn.net/source/2320280
驱网介绍:http://bbs3.driverdevelop.com/read.php?tid-120461.html
二. USB 设备硬件结构
1. 主从结构
首先从硬件角度介绍USB,本文档的任务在于内核开发,硬件知识只能点到为止。 USB的全称是Universal Serial BUS(通用串行总线)。硬件上,他有两个显著的特点:串行数据传输、支持热拔插。从1996年1月第一个版本发布到今天,USB已经经历了四个版本:1.0、1.1、2.0和3.0。其应用遍及各个领域,方方面面。
USB的另外一个特点是他采用主从结构。两个可以互联的设备,一定有主从之分。这导致了两台主机(主设备)或者两台MP3(从设备)之间,没有办法互联。只能在设备(MP3)和主机之间建立主从互联关系。当然,后来出现了OTG,可以让设备更换角色。但并未能改变主从结构的本质。
能成为USB主机,就一定要具备两种设备:USB主控制器、USB根集线器。主控制器用来处理根集线器上的数据,交给系统处理;根集线器用来连接多个外部设备。读者请注意不能把这里的根集线器和普通USB集线器全然划等号,应当把USB集线器也理解为USB外部设备的一种,不是主机的组成部分。
图1 主机和设备
从上图我们了解到,设备->集线器->控制器->系统,就像碗中杯,杯中勺一样,层层套叠。我们在使用的电脑,每台电脑都有若干个控制器,控制器上有一个或多个根集线器,集线器上又对外暴露出一个或多个USB A型接口让外部设备连接。将设备管理器的视图模式选为“按连接排序设备”后,可看到下图所示的层次结构。
图2 控制器、集线器和设备
最上层是USB EHCI接口的控制器,中间层是控制器上唯一的根集线器,最下层是连接在根集线器上的设备。
每个USB控制器,作为一个USB族群之灵魂,其驱动程序负责为子设备分配总线地址。总线地址为7位宽,由于控制器自己占一个地址,故而最多可提供(27-1 = 127)个子设备地址,也就是说,每个控制器上最多能连接127个子设备。并且,这个数目包含了根集线器。
电器特性方面,标准USB接口有4个金属针脚,对应着USB线中,就是4根金属线:两根电源线,两根数据线。两根电源线,一个接5V电源,一个接地。两根数据线,实现了数据的差分传输,提高了稳定性,等于是一根线,也就是“串行”之由来了。
说到电源线,就说说设备供电。USB设备可以自己供电,也可以从总线获取电源。总线获取的电源,就是通过5V电源线传过来的。像U盘、鼠键这类小型设备,5V电源或者100mA电流足以满足其设备需求,故而多从总线获取电源;移动硬盘、打印机、专业USB声卡这种较大设备,往往需要外置电源,也就是自己供电。巧得很,我发现XP系统中的根集线器驱动程序,有自定义的电源属性页,反映了集线器设备的供电情况,截图如下:
图3根集线器的电源状态
由上图可以看出,此根集线器是自供电的,可用电量高达500mA/每个端口,两个端口就到达了1A电量,这是总线供电无法达到的。
再说USB设备的拓扑结构。分为三层:硬件接口、统筹模块、多个功能模块。借助于这种结构,实现了多种功能集纳于同一个设备的优势。这样的话,鼠标、键盘、游戏柄三者合一,就不是什么难事。
图4 USB设备拓扑结构
有时候,这种结构令我联想到一把折扇。折起来的时候,只能看到一个骨架;打开的时候,却变成了十数背大。我是把这些骨架,当成了USb设备中的功能模块了。
如何理解上面的拓扑图呢?从硬件自身来看,设备是唯一的。故而对外的接口也是唯一的。这就对应着图中的“总线接口”模块。然则,设备存在的目的,当然是为了完成一定的工作,他能实现多少功能,即表示内部有多少独立的“功能模块”。现在好了,多个功能,同处一个设备,岂不打架了?需要有统筹单位来协调资源,这就得请出“逻辑设备”来。
很难在设备中用手指出来,那个部位对应着“逻辑设备”,因为拓扑结构中的模块都是抽象的。固件中的某几个函数,某几行代码,可能就构成了一个逻辑模块。
我们不用去考虑USB固件代码,如何运作甚至如何书写,但读者要有个认知底线:USB设备中是有程序在运行的。有人奇怪设备是怎么和主机通信、连接的,想破脑袋,却想不到设备中也有个CPU,也有运行着的代码。
CY001开发套件中包含了固件代码,C51编程。C51和C语言很类似,入手会比较顺。固件开发是一件很艰难的工作,未必比驱动开容易。但二者没有可比性,简直就是两个世界的。
USB的“从主”关系还有另外一层含义:主机向设备发布命令,设备相应命令;主机如果没有命令发送,设备不能主动联系主机。“主人”不言语,“仆人”难吱声。即使是在进行输入传输的情况下——也就是说设备向主机发送数据——数据过程也是在主机的指导下完成的。
这很容易就牵扯到另一个话题:USB中断。中断从来都是主动的,现在USB设备处于“仆人”地位,哪里能够主动呢?所以众所周知,USB中断是 “伪中断”。
真正的中断,不管硬中断也好,软中断也好,一定是主动发生的。即中断源出现了,相应的中断事件即随之产生。中断是一件“意外”,并且“主动”发生。
USB的伪中断是另外一回事:USB设备总是把数据保存在设备内存中,等待主机来索取;如果主机果然来索取,就立刻把数据交给它;否则要么仍旧一直保存着,要么当新的中断数据到来时被覆盖。
从这个意义上来说,USB设备的中断端口和批量端口本质上就非常像了,将批量端口加上主机轮询,差不多也就变成一个中断端口了。后文《内核开发》部分会详细讲述批量、中断端口的读写。