【笔记】USB概述及协议基础

时间:2024-04-15 19:29:54
受不了xxxx恶心人的行为,遂搬迁至博客园。
始发:2017-10-15 15:55:53

USB采用树形拓扑结构,主机侧和设备侧的USB控制器分别称为主机控制器(Host Controller)和USB设备控制器(UDC),每条总线上只有一个主机控制器,负责协调主机和设备间的通信,而设备不能主动向主机发送任何消息。

 

USB工作于主从模式(master/slave),设备与设备之间、主机与主机之间不能互联。
USB OTG支持同一个设备在不同场合下在主从之间切换,但依然是主从关系,OTG增加了一种MINI USB接头,比普通4线USB多了一条ID标识线,用来表明它是主机还是设备。

 

通常说的USB主机具有多个USB主控制器(host controller)和根集线器(root hub)。主控制器负责数据处理,而hub提供一个连接主控制器与设备之间的接口和通路。
USB集线器(USB hub),它可以对原有的USB口在数量上进行扩展,进而获得更多的USB口。
所有的数据传输都由主机发起,设备只是被动的应答。

 

USB主机控制器有3种规格:

  • OHCI (Open Host Controller Interface)
  • UHCI (Universal Host Controller Interface)
  • EHCI (Enhanced Host Controller Interface)

OHCI: 驱动程序用来为非PC系统上以及带有SiS和ALi芯片组的PC主板上的USB芯片提供支持。
UHCI: UHCI 是 Intel 提出来的,它是一种 USB 主机控制器的接口规范,遵守它的硬件称为 UHCI 主机控制器。
EHCI: 由USB 2.0规范所提出,USB 2.0 定义了低速(ls),全速(fs),高速(hs)传输。 EHCI 仅仅支持高速传输。
UHCI 的硬件线路比OHCI简单,所以成本较低,但需要较复杂的驱动程序,CPU负荷稍重。


一个完整的USB数据传输过程如下:
首先由USB主控制器发出命令和数据.通过根集线器,再通过下面的集线器(如果有)发给USB设备;
设备对接收到的数据进行处理后,返回一些信息或者数据,它首先到达其上一层的集线器,上层的集线器再交给更上层的集线器,一直到USB主控制器为止;
最终,USB主控制器将数据交给计算机的CPU处理。

标准的USB连接线使用4芯:5V电(VBus)、差分数据线负(D-)、差分数据线正(D+)、GND。
OTG比标准的多了一条身份识别(ID)线。
USB使用差分传输模式,因而两条数据线,低速(1.5Mb/s)、全速(12Mb/s)模式下采用电压传输模式,高速(480Mb/s)电流传输模式

USB使用的是NRZI编码方式:当数据为0时,电平翻转;数据为1时,电平不翻转。
为防止出现长时间电平不变化(这样不利于时钟信号的提取),在发送数据前要经过位填充(bit stuffing)处理。
位填充处理的过程是这样的:
当遇到连续6个数据1时,就强制插人一个数据0。经过位填充后的数据,由串行接口引擎(SIE)将数据串行化和NRZI编码后,发送到USB的差分数据线。
在接收端.刚好是一个相反的过程。接收端采样数据线,由SIE将数据并行化(反串行化),然后去掉位填充(反位填充),恢复出原来的数据。
通常,我们使用现成的USB芯片,如位填充、串行化、反串行化、 CRC校验等处理过程,芯片内部的硬件已经帮我们做好,因此可以不用关心这些细节,只需要对这个过程有个了解就可以。当然,如果是自己设计一个USB核,或者用软件来模拟USB口,那么这些过程就必须自己来做了。

 

USB协议规定:设备在未配置之前,可以从VBus上最多获取100mA的电流;
在配置之后,最多可从VBus上获取500mA的电流。VBus是5V的电压,具体的参数请参看USB协议。

 

USB描述符记录了设备的类型、厂商ID、产品ID(通常通过它们来加载对应的驱动)、端点情况、版本号等信息。

  • 设备描述符:关于设备的通用信息,如供应商ID、产品ID和修订ID,支持的设备类、子类和适用的协议以及默认端点的最大包大小等。在Linux内核中,USB设备用usb_device结构体来描述,USB设备描述符定义为usb_device_descriptor结构体。
  • 配置描述符:此配置中的接口数、支持的挂起和恢复能力以及功率要求。USB配置在内核中使用usb_host_config结构体描述,USB配置描述符定义为usb_config_descriptor结构体。
  • 接口描述符:接口类、子类和适用的协议,接口备用配置的数目和端点数目。USB接口在内核中使用usb_interface结构体描述, USB接口描述符定义为usb_interface_descriptor结构体。
  • 端点描述符:端点地址、方向和类型,支持的最大包大小,如果是中断类型的端点则还包括轮询频率。在Linux内核中,USB端点使用 usb_host_endpoint结构体来描述,USB端点描述符定义为usb_endpoint_descriptor结构体。
  • 字符串描述符:在其他描述符中会为某些字段提供字符串索引,它们可被用来检索描述性字符串,可以以多种语言形式提供。字符串描述符是可选的,有的设备有,有的设备没有,字符串描述符对应于usb_string_descriptor结构体。

各个描述符间关系:

或者:

总结如下:

设备通常有一个或多个配置;
配置通常有一个或多个接口;
接口通常有一个或多个设置;
接口有零或多个端点。

 

USB主机在检测到USB设备插入后,就要对设备进行枚举了,进而从设备读取各种描述符信息,这样主机就可以根据这些信息加载合适的驱动,从而知道是什么样的设备、如何通信等。
下面介绍枚举的详细过程。
① USB主机检测到USB设备插人后,就会先对设备复位。 USB设备在总线复位后其地址为0,这样主机就可以通过地址0和那些刚刚插入的设备通信。USB主机往地址为0的设备的端点0发送获取设备描述符的标准请求(这是一个控制传输的建立过程)。设备收到该请求后,会按照主机请求的参数,在数据过程将设备描述符返回给主机。主机在成功获取到一个数据包的设备描述符并且确认没有错误后,就会返回一个0长度的确认数据包(状态过程)给设备,从而进人到接下来的设置地址阶段。

这里需要注意的是,第一次主机只会读取一个数据包的设备描述符。标准的设备描述有18字节,有些USB设备的端点0大小不足18字节(但至少具有8字节),在这种情况下, USB主机也是只发送一次数据请求,多余的数据将不会再次请求。因此,如果当设备端点0大小不足18字节时,就需要注意到这个问题。也就是说在第一次获取设备描述符时.只需要返回一次数据即可,不要再等主机继续获取剩余数据(如果还有),因为主机不会这么干的。当主机成功获取到设备描述符的前8字节之后(USB协议规定端点0最大包长至少要有8字节),它就知道端点0的最大包长度了,因为端点0最大包长度刚好在设备描述符的第八字节处。

② 主机对设备又一次复位。这时就进人到了设置地址阶段。USB主机往地址为0的设备的端点0发出一个设置地址的请求(控制传输的建立过程)。新的设备地址包含在建立过程的数据包中。具体的地址由USB主机负责管理,主机会分配一个唯一的地址给刚接入的设备。USB设备在收到这个建立过程之后,就直接进入到状态过程,因为这个控制传输没有数据过程。设备等待主机请求状态返回(一个输人令牌包)。收到输入令牌包后,设备就返回0长度的状态数据包。如果主机确认该状态包己经正确收到,就会发送应答包 ACK给设备,设备在收到这个ACK之后,就要启用新的设备地址了。这样设备就分配到了一个唯一的设备地址,以后主机就通过它来访问该设备。
③ 主机再次获取设备描述符。这次跟第一次有点不一样。首先是主机不再使用地址来访问设备,而是新的设备地址;另外,这次需要获取全部的18字节的设备描述符。如果你的端点0最大包长小于18字节,那就会有多次请求数据输入(即发送多个IN令牌包)。 
④ 主机获取配置描述符。配置描述符总共为9字节。主机在获取到配置描述符后,根据配置描述符中所描述的配置集合总长度.获取配置集合。获取配置描述符和获取配置描述符集合的请求是差不多的,只是指定的长度不一样。有些主机干脆不单独获取配置描述符,而是直接使用最大长度来获取配置描述符集合,因为设备实际返回的数据可以少于指定的字节数。配置集合包括配置描述符、接口描述符、类特殊描述符(如果有)、端点描述符等。接口描述符、类特殊描述符、端点描述符是不能单独获取的,必须跟随配置描述符以一个集合的方式一并返回。

 

USB有四种传输类型:控制传输中断传输批量传输等时传输

  • 控制传输(Control)
    Control endpoints are used to allow access to different parts of the USB device. They are commonly used for configuring the device, retrieving information about the device, sending commands to the device, or retrieving status reports about the device. These endpoints are usually small in size. Every USB device has a control endpoint called “endpoint 0” that is used by the USB core to configure the device at insertion time. These transfers are guaranteed by the USB protocol to always have enough reserved bandwidth to make it through to the device.

  • 中断传输(Interrupt):Interrupt endpoints transfer small amounts of data at a fixed rate every time the USB host asks the device for data. These endpoints are the primary transport method for USB keyboards and mice. They are also commonly used to send data to USB devices to control the device, but are not generally used to transfer large amounts of data. These transfers are guaranteed by the USB protocol to always have enough reserved bandwidth to make it through.

  • 批量传输(Bulk)
    Bulk endpoints transfer large amounts of data. These endpoints are usually much larger (they can hold more characters at once) than interrupt endpoints. They are common for devices that need to transfer any data that must get through with no data loss. These transfers are not guaranteed by the USB protocol to always make it through in a specific amount of time. If there is not enough room on the bus to send the whole BULK packet, it is split up across multiple transfers to or from the device. These endpoints are common on printers, storage, and network devices.

  • 等时传输(Isochronous)
    Isochronous endpoints also transfer large amounts of data, but the data is not always guaranteed to make it through. These endpoints are used in devices that can handle loss of data, and rely more on keeping a constant stream of data flowing. Real-time data collections, such as audio and video devices, almost always use these endpoints.

Control and bulk endpoints are used for asynchronous data transfers, whenever the driver decides to use them. Interrupt and isochronous endpoints are periodic. This means that these endpoints are set up to transfer data at fixed times continuously, which causes their bandwidth to be reserved by the USB core.

 

资料:

1、《圈圈教你玩usb》

2、《linux设备驱动开发详解》

3、Linux Device Drivers, Chapter 13: USB Drivers

4、http://www.usb.org/home

5、Linux那些事儿之我是USB系列