USB总线基础

欢迎转载,转载请注明出处。

前言
在众多的通信总线协议中,USB总线协议拥有绝对的地位,因此对于嵌入式开发人员来说,掌握USB总线协议是非常有必要的;但对USB总线协议的理解,并不像前面I2C、SPI协议一样那么容易。所以在写这篇内容时,为了能让大家更容易理解和掌握USB协议,我也翻阅了大量的资料,目的让内容更准确和通俗易懂。建议在阅读这篇文章前,大家能先浏览一下前几篇文章,或者对I2C、SPI这些总线协议有一定的了解。因为USB接口协议的确有些费解,所以本文如果有理解不足或疏漏之处,欢迎大家批评指正。

定义
通用串行总线USB(universal serial bus)是由Intel、 Compaq、Digital、IBM、Microsoft、NEC、Northern Telecom等7家世界著名的计算机和通信公司共同推出的一种新型接口标准。它基于通用连接技术,实现外设的简单快速连接,达到方便用户、降低成本、扩展PC连接外设范围的目的。

接口电路


标准的USB连接线使用4芯电缆(OTG使用5芯电缆,多了一根身份识别线,后面简要介绍两者区别),如上图:电源线(VBUS)、差分数据线D+和D-、接地线(GND)。因为USB使用的是差分传输模式,所以有两条数据线(注意:这里的两条数据线和SPI总线的MISO/MOSI两条数据线不一样,SPI虽然也有两条数据线,但主从设备的读写操作使用的两条独立的数据线,MISO(master output slave input)主机输出从机输入线,具体参照前篇的SPI总线介绍),USB2.0中有低速(1.5Mbps)、全速(12Mbps)和高速(480Mbps)三种模式,USB3.0又新加了一种超速模式(5.0Gbps)。
如果仔细观察USB接口,例如U盘口,你就会发现U盘口里有4个金属片,中间两个比外面两个短一些;其实中间是数据线,外面是电源线,之所以电源线比数据线长,是为了实现热插拔。在接通的时候先通上电源线,再接上数据线;同样断开的时候,先断开数据线,后断开电源线,这样就保证了数据线接上时,电源是供电的。
USB传输时使用电压和电流两种传输方式,在低速和全速模式下使用电压传输,在高速模式下使用电流传输。

系统架构
USB采用总线拓扑结构,包括主机和设备、物理拓扑结构、逻辑拓扑结构以及客户软件层与应用层的关系。

物理拓扑结构

在USB系统中,USB设备与主机采用星型连接方式。图中的HUB称为集线器,可以把Hub看成是一类特殊的USB设备,作为一组*USB设备的连接点。主机中有个根HUB,主机利用这个根HUB可以提供若干个连接点,USB设备既可以直接连接到主机上,也可以连接到HUB上,理论上USB最多支持127个USB设备,因为USB内部使用7bit来标志设备的地址,其中地址0是预留给未初始化的设备的*(这在后面会提到,为什么要把0地址预留出来)。在USB的拓扑结构中,拓扑层数是有限制的,USB1.1规定最多4层,USB2.0最多6层。

总线拓扑结构

虽然在物理结构上,USB设备通过Hub连接到主机;但在逻辑上,主机是直接与各个逻辑设备通信的,就像这些设备是直接被连到主机上一样。虽然USB系统的工作都是从逻辑角度来看待的,但主机对物理结构也有一定的了解;当一个Hub被移除时,该Hub上连接的USB设备应该一起被移除,这是由物理结构决定的。

逻辑结构
这里先举个例子,让大家明白配置、接口和端点的关系。
例如一个USB播放器带有音频、视频功能,另外还有触摸屏和按钮。 那这个USB播放器的配置就可以有几种:
配置1:音频(接口)+触摸屏(接口)
配置2:视频(接口)+按钮(接口)
配置3:音频(接口)+视频(接口)+触摸屏(接口)
其中音频接口、视频接口、触摸屏接口和按钮接口都需要一个驱动程序。
配置和接口是为了更加方便的管理端点抽象出来的概念。每个USB设备都可以包含一个或多个配置,不同的配置使设备拥有不同的功能组合;而每个配置有多个接口组成。在USB协议中,接口由多个端点组成,表示一个基本功能,是USB设备驱动程序的控制对象,一个功能复杂的USB设备可以有多个接口;而接口是端点的汇集。
物理结构图中的复合设备,指的就是具有多个接口的设备,在主机端会把USB复合设备的每个接口当做一个功能设备来看待。

端点

USB设备中,唯一可寻址部分是设备端点。位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据。主机和设备的通信最终作用于设备上的各个端点,它是主机与设备间通信流的一个逻辑终端。
每个USB设备有一个唯一的地址,这个地址是在设备连上主机时,由主机分配的,而设备中的每个端点在设备内部有唯一的端点号,这个端点号是在设计设备时给定的,每个端点都是一个简单的连接点或者支持数据流进设备,或者支持其流出设备,两者不能同时存在。
举个例子来说:USB总线就像是高速公路,行驶在高速公路上的汽车就像是收发的数据,USB端点就类似于高速公路的收费口。
由前面USB的逻辑结构介绍可知,一个USB逻辑结构可以看成端点的集合。主机和设备的通信都可以理解为对端点的操作。主机在与设备端点通信前,都要先完成端点的配置工作,在这之前端点都处于一种不确定状态,关于端点的描述可以有以下几点描述:总线访问频率/延时要求、带宽要求、端点号、差错控制要求、端点可以接收或传递的最大分组、端点的传送类型、如果是同步传送方式,还要包括端点和主机之间的数据传送方向。
前面说到,USB设备的地址是由主机分配的,那么我们就该有疑问?主机给设备分配地址前,是通过什么与设备通信的,主机在不知道设备地址的情况下,如何找到这个需要分配地址的设备并建立通信?这就不得不说0地址处的端点0,所有的USB设备都有端点0,该端点用于对USB设备的初始化配置操作,端点0提供了对设备配置信息的访问权,通过端点0可以访问USB状态和控制操作,并且端点0,是在设备接入和上电时就进行配置的。,通过端点0为设备分配好地址后,主机就可以利用设备地址与设备完成通信,这也是设备枚举的过程,具体的操作步骤见下面的设备枚举介绍。

描述符
USB设备内部都有类似配置寄存器这样固定格式的数据,通过这些数据,USB主机就可以获取USB设备的类型、生产厂商等信息。这组固定格式的数据称为USB描述符。一个标准的USB设备,应该有5种USB描述符:设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符。
一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,一个配置描述符可以包含多个接口描述符,一个接口由多少个端点组成就用多少个端点描述符。这正好和USB的逻辑结构相对应。

设备描述符:设备所使用的USB协议版本号、设备类型、端点0的最大包大小、厂商ID(VID)和产品ID(PID)、设备版本号、厂商字符串索引、产品字符串索引、设备序列号索引、可能的配置数等。
配置描述符:记录配置所包含的接口数、配置的编号、供电方式、是否支持远程唤醒、电流需求量等。
接口描述符:记录接口的编号、接口的端点数、接口所使用的类、子类、协议等。
端点描述符:端点号及方向、端点的传输类型、最大包长度、查询时间间隔等。
字符串描述符:提供一些方便人们阅读的信息,它不是必需的。
设备枚举
在说设备枚举前,先说说USB设备的插入检测机制;在主机USB接口的D+和D-上,都有一个15K的电阻接地,当无设备接入时,数据线处于低电平;在USB设备端的D+和D-上也接有1.5K的电阻,如果D+上接了1.5K的上拉电阻,就表示该设备是高速或全速设备,如果D-上接了1.5K的上拉电阻,就表示该设备是低速设备。这样当设备接入时,主机端的USB接口上的D+或D-就会被拉高,系统识别到外部设备接入。
这里需要注意的是,高速设备首先会被识别成全速设备,然后再通过集线器和设备确认,最后切换到高速模式下。

复位
主机在检测到USB设备的插入后,首先做的是将差分数据线同时拉低一段时间,让USB设备复位。复位后USB设备的地址变为0,然后主机往地址0处的设备的端点0发送获取设备描述符的请求。

分配地址
在获取设备描述符后,主机再往地址0处发送设置地址请求,主机会分配一个唯一的地址给USB设备,在通信建立成功后就会启用新的地址,以后主机访问这个设备时,就通过这个地址来访问。

获取设备描述符
地址设置成功后,要重新获取设备描述符。这里之所以要重新获取设备描述符,是因为一个标准的设备描述符有18个字节,但有些USB设备的端点0大小不足18个字节,因为在复位时,主机只读取一次USB设备信息,所以即使端点0的大小不足18个字节,主机也不会读取多次。USB协议规定端点0的大小至少为8个字节,但这8个字节已经包含复位阶段需要的所有信息,所以复位阶段获取的设备描述符可能是不完整的,在地址设置完成后,这里重新获取完整的设备描述符,如果端点0大小不足18个字节时,这里会多次请求数据输入。

获取其它描述符
在获取设备描述符后,主机还要获取其它描述符,配置描述符,接口描述符,端点描述符等。

数据传输
USB有四种数据传输类型:

控制传输:支持外设与主机之间的控制,状态,配置等信息的传输;为外设与主机之间提供一个控制通道,在设备连接时用来对设备进行设置,还可对指定设备进行控制,如通道控制。当USB设备初次安装时,USB系统软件使用控制数据对设备进行设置,设备驱动程序通过特定的方式使用控制数据来传送,数据传输是无损的。
批量传输:大批量产生并使用的数据,在传输约束下,具有很广的动态范围。支持打印机、鼠标和键盘等输入设备。在硬件级上可使用错误检测可以保证可靠的数据传输,并在硬件级上引入了数据的多次传输,另外根据其他一些总线动作,被大量数据占用的带宽可以相应的进行改变。
中断传输:用来描述或匹配人的感觉或对特征反应的回馈,支持像游戏手柄,鼠标和键盘等输入设备。这些设备与主机间的数据传输量小,无周期性,但对相应时间敏感,要求马上相应。中断数据一般由事件通告,特征及坐标号组成。
等时传输:也叫同步传输,支持周期性,有限的时延和带宽且数据传输速率不变的外设与主机间的数据传输。但该类型的数据传输没有差错校验,所以不能保证正确的数据传输。
USB协议
事务:一次传输由一个或多个事务组成,分为IN事务和OUT事务
包:一个事务由一个或多个包组成,可分为令牌包(Setup)、数据包(data)、握手包(ACK)和特殊包
域:一个包由多个域组成,域可分为同步域(SYNC)、标识域(PID)、地址域(ADDR)、端点域(ENDP)、帧号域(FRAM)、数据域(DATA)、校验域(CRC)
如下图,可以看到有多个Transfer(传输),每次传输包含多个Transaction(事务),每个事务又包含多个Packet(包),每个包都是从sync开始,以EOP结束。
下图是一个USB设备的枚举过程,我们可以看到第一次传输Transfer0是一个控制传输(Control),在获取到相应数据后,主机会发出Reset命令,复位USB设备。这和上面描述的设备枚举过程相吻合。


在下面这张图可以看到,一直到第十次传输,都是控制传输,并且后面几次的控制传输中,都没有Reset信号。由此可见复位USB设备发生在第一次传输。到第十一次传输时,变成了中断传输(Interrupt),这是因为前面几次传输是在获取USB描述符,即设备枚举过程,因为获取USB描述符时,用的是控制传输,所以在图片中看到前几次都是控制传输(之所以有多次传输是因为USB有多种描述符),因为这是一张USB鼠标的数据包分析图,所以在设备枚举后,紧接着是中断传输。


USB是以包为单位进行数据传输的,使用包的好处在于,可以灵活地定义数据的传送格式,从而适应各种各样的串行设备,这也是就是所谓的通用串行总线。
我们虽然知道了事务、包和域等概念,但数据传输方向、传输地址、传输类型等信息,也是数据传输时必须知道的,为了对应这些内容,我们专门定义的一套基于packet的协议,让数据传输时都遵从这套协议。
USB的传输协议中有一点比较特殊的是,第一个数据包都是由主机发起的,就算从机要发送数据给主机,也要在主机发送第一个数据包后,从机再开始发送数据。

从下面的图片中,可以看到每个Transaction的第一个Packet都是由主机发起的(Dir中的”–>”表示主机向从机发送数据,“<–”表示从机向主机发送数据),在Transacion5中,从机向主机发送数据时,也是由主机先发送一个“IN”请求,然后从机再向主机发送数据。传输完成后,会发送一个“ACK”确认信号,表示数据传输完成。

总结
与I2C,SPI等总线协议相比,USB要更为繁琐,理解起来比较困难。这里提出几张USB设备的数据包分析,是为了有助于让大家更好的理解USB协议。有了这些USB基础,再去理解USB驱动,相对来说要简单许多。这里写的也只是个人理解,有很多地方说的还不够详细,或者有理解错误的地方,欢迎大家批评指正。
————————————————
版权声明:本文为CSDN博主「如鱼饮水」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_32959415/java/article/details/78045742

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值