USB(Universal Serial Bus)通常指通用串行总线,日常生活中常见的计算机USB集线器控制器,手机等终端设备,USB线缆等,都是用了USB进行连接。USB技术体系规定了USB总线规范和USB通信协议,这意味着只要遵循USB技术要求制作的设备,都能通过USB总线进行通信。其中USB2.0规范是目前较为广泛被运用,且易于理解的,以下内容都以USB2.0为主线,穿插USB3.X,USB4.0的形式进行讨论
在过去,计算机为了连接不同需求不同速度的外部设备(包括鼠标,键盘和打印机,扫描仪这类通用输入输出设备,还有其他诸如拥有特殊功能的专用设备),通常会预留很多设备接口,多样化接口解决不同设备连接需求的同时,也带来了新的问题:
那为何不开发出一个通用的协议标准,统一计算机外设的硬件连接接口和数据传输协议。在1994年底,Intel联合Microsoft,IBM,Compaq,NEC等公司推出USB总线规范
USB协议的目标,就是要解决以下+历史问题:
经过二十几年的发展,USB协议已经迭代了多个版本,分别是:
协议版本 | 更新内容 |
---|---|
USB1.X | USB1.0发布于1996年,传输速率为1.5Mb/s,USB1.1发布于1998年,传输速率提升到12Mb/s。USB1.X提供了对HUB和HID设备的支持 |
USB2.0 | USB2.0发布于2000年,传输速率提升到了480Mb/s。USB2.0相当于是USB1.X的升级版 |
USB3.X | USB3.0发布于2008年,传输速率提升到了5Gb/s,USB3.1发布于2013年,传输速率提升到了10Gb/s。USB3.X都提供对USB2.0设备和接口的向后兼容,此外USB3.X还提供了电源支持 |
USB4.0 | USB4.0是当前最新的USB协议,发布于2019年,传输速率达到了惊人的40Gb/s。USB4.0提供了对USB3.X和USB2.0的向后兼容,此外USB4.0还提供了ThunderBolt 3协议支持 |
USB总线系统是主从式结构的,它可以由一个主机和一个/多个从机构成:
数据传输一般只能在主机和从机之间进行,主机与主机,从机与从机之间一般是不能进行数据交换的。
USB OTG(On The Go)技术
该技术在物理连接上多使用了一根ID数据线,用作身份标识。使用此技术的设备可以在主机和从机之间切换。例如支持USB OTG技术的手机,在连接计算机时可以当作从机,当使用专用数据线同USB设备连接时有又可以作为主机,可外接USB设备包括U盘,键盘等
但从本质上讲,USB OTG技术依旧是遵循主从结构的
数据传输是由主机进行主导的,从机只是被动地进行应答,无论是输入/输出数据,都是由主机端发起,从机收到主机的请求后,按照要求执行对应操作
以下是USB总线系统的拓扑结构图:
结合拓扑图,可以很好地理解USB总线系统的特点:
地址0被USB根集线器和未初始化的从机临时使用,会出现冲突吗?
不会,当所有的从机都未初始化时(包括根集线器),USB主机会先对根集线器进行初始化,因为此时物理上只有根集线器同主机相连,在根集线器初始化中和初始化完成后,都以地址0作为自身的默认地址。而当根集线器初始化完毕后,主机会开始初始化根集线器下的设备,根集线器下的设备未初始化时的默认地址都会是地址0,但这和根集线器自身地址为地址0并不冲突,因为此时通过地址0同未初始化的设备通信,本质上是通过根集线器(地址0)间接的同USB从机通信
USB总线系统实际上真的可以连接127个从机吗?
不可以,可连接从机数量是要比127少的。因为要考虑以下因素
- 电力约束:过多USB集线器串联会导致电力供应不足,部分从机可能会不能正常工作
- 总线带宽:连接过多USB从机时,总线带宽的分配会变得十分有限,导致数据传输出现问题
- 总线长度:这里的长度指的是物理长度,USB线过长会导致电信号质量变差,数据包丢包变多
- USB集线器占位:USB集线器也会占用地址,所以实际上真正能发挥作用的从机会更少
综上来说,USB总线上连接的设备是会受到多种因素的限制的(对于USB3.0没有这种限制)
从总线拓扑图的结构中,单独对一对USB主机/从机进行数据传输分析。从逻辑上看,它们的关系可以抽象成下图,USB主机通过用户端软件中的Buffer,通过USB总线提供的管道,和USB从机上的多个端点进行连接。USB主机/从机间的数据传输,其实就是通过用户端软件的Buffer和端点进行数据交换
端点是USB从机中可以收发数据的最小单位,你可以将端点理解为用于数据传输的Buffer。本质上,每个USB从机在逻辑上都可以理解为多个端点的集合,其中的多个端点都是相互独立的。通过设备地址+端点地址,USB主机可以准确的定位到端点(此处可以结合USB数据格式中的设备地址进行理解),从而进行数据交换
端点分为:
管道是USB主机和USB从机之间数据传输的模型,共有两种类型的管道:
可以看出,管道的类型和端点的类型是有对应关系的:控制端点-信息管道/普通端点-流管道。值得注意的是,任何USB从机,在连接到总线后都会存在一个默认的信息管道,即控制管道,USB主机会通过这个管道获取USB从机设备的描述符(此处可以结合USB描述符的内容进行理解)
随着USB协议的不断更新,USB硬件接口的类型也不断迭代,常见的USB接口分别有USB Type-A,USB Type-B,USB Type-C这几个大类,每种接口都分有公头(插入)和母座(被插入),以下仅列出公头的图例:
USB Type-A接口分为标准USB Type-A(根据支持的USB数据协议分为2.0版本和3.0版本),USB Micro-A,USB Mini-A
其中标准USB Type-A接口是最常见的一种,计算机上USB根集线器通常都会有USB Type-A接口的母座。至于USB Micro-A接口和USB Mini-A接口都比较少见,通常在过去的数码设备,如MP3,随身听上会看到
USB Type-B接口分为标准USB Type-B(根据支持的USB数据协议分为2.0版本和3.0版本),USB Micro-B(根据支持的USB数据协议分为普通版本和3.0版本),USB Mini-A
标准USB Type-B接口常用于打印机,扫描仪等者大型设备上,其体积较大,连接上后不容易掉落,也不容易扯断。USB Micro-B接口由于其体积更小,常用于2018年前的一些安卓手机等便携设备上,在当时甚至一度成为了安卓手机的数据和充电标准接口,近几年已经逐渐被USB Type-C接口取代。USB Micro-B(3.0)接口由于其支持USB3.0传输协议的特性,一般是在移动硬盘上使用。USB Mini-B接口已经很少见到,通常在过去的数码设备,如MP3,随身听上会看到
USB Type-C接口如今已经取代了很多的老旧接口,成为一种真正的通用型接口,这是由于其硬件规格上,支持更快的传输速率,更高的供电规格,更高的使用寿命,同时还有大众最喜欢的:支持正反插
USB通过硬件接口PIN脚上的差分信号传输数据,PIN脚的数量,在不同版本的USB协议以及不同类型的USB接口中都是不一样的
差分信号是什么
差分信号传输是一种常见的信号传输方式,它通过两根相反差分信号线之间电信号(电压或电流)的差值来表示数据。差分信号由于使用差值来表示数据,所以有很强的抗干扰能力,因为一旦出现信号影响的因素,虽然会造成两根信号线上的电信号波动,但是由于数据用电信号之间的差值表示,那么影响因素造成的电信号波动会相互抵消掉,从而实现数据的稳定传输
USB2.0传输协议要求,硬件物理接口至少有4个PIN,4个PIN分别是:
常见的标准USB Type-A接口,标准USB Type-B接口都是4个PIN脚的
USB3.0传输协议由于对数据传输速率进行了提升,所以在USB2.0要求的硬件基础上,增加了超高速数据差分信号传输接口,所以共需要9个PIN脚。9个PIN分别是:
常见的支持USB3.0传输协议的USB Type-A接口,是使用9个PIN脚的。此外从USB Type-A接口的 颜色上也能进行分辨,支持USB3.0传输协议的接口一般都有蓝色的塑料件
5PIN的PIN脚数常见于USB Micro-A接口,USB Mini-A接口,USB Micro-B接口,USB Mini-B接口,其支持的协议依旧是USB2.0,多出的第5PIN,是为了支持USB OTG的功能,用作身份ID标识线。5个PIN分别是:
特别的是,USB Micro-B接口3.0版本是支持USB 3.0协议的,所以它的PIN脚比USB Micro-B接口普通版本要多,外形上也有很大改变,但似乎因为结构设计上不太合理,所以并没有被广泛使用,尤其是USB
Type-C接口出现后
24PIN的PIN脚数仅能用在USB Type-C接口上,因为支持正反插,所以实际上24个PIN脚对应的作用是有重复的。这24个PIN脚分别是:
24PIN脚的USB Type-C接口又被称为全功能USB Type-C接口
16PIN的PIN脚数其实是24PIN脚USB Type-C的阉割版,由于部分设备可能使用不到USB3.0的速度,所以可以把超高速差分信号相关的8个引脚去掉。这样的USB总线系统在硬件接口上使用USB Type-C接口,传输协议上就使用USB2.0传输协议。
6PIN的PIN脚数其实页是24PIN脚USB Type-C的阉割版,只不过这次把USB数据传输相关的差分信号相关引脚全部去掉,仅保留供电引脚。6PIN的接口,仅支持充电,不能进行数据传输
USB1.X低速设备使用3.3V差分信号
USB1.X全速设备,USB2.0-USB4.0都使用5.5V差分信号传输
D+线电压>D-线电压表示信号1,反之表示信号0
USB总线在传输数据时,是按位进行传输的,所以是串行通信,同时USB是小端字节序传输,这意味着,串行传输时,应该先传输数据的LSB(最低有效位)。例如数据0X1234,通过USB总线传输时,会先传输0X34,再传输0X12
USB2.0规范中,USB的数据传输仅支持半双工,因为仅有一对差分信号线,数据方向只能是主机->从机或从机->主机。
USB3.0规范中,USB的数据传输支持全双工,由于硬件上增加了超高速差分信号线,传输协议上也进行了更新,所以同一时刻,数据可以从主机->从机/从机->主机
USB以异步传输的方式,USB主机和USB从机的时钟频率都分别由自身提供,但是在USB从机枚举时,会共同确定USB版本,以确定数据传输速率。但是仅仅如此的话,USB主机和USB从机在运行一段时间后,时钟频率上还是会有累积误差,这会造成数据解读出错,所以USB主机会在每帧(下面会提到)的时间都会主动向USB从机发送同步信号(帧首包),以消除USB主机和USB从机之间的累积频率误差
帧和微帧属于USB系统中物理层时间基准的概念。USB低速模式,全速模式下,每个帧的长度为1ms;而高速模式下,每个微帧的长度为125us,即1帧=8微帧,帧的长度是固定的
由于USB总线上可能会存在多个从机,如果同一时间内,有多个从机同时要使用总线的话,会产生冲突,所以USB协议规定了帧/微帧的时间概念,USB主机每隔1帧/1微帧(即每1ms/125us),会将总线的使用权指定给某个USB从机,USB从机在这帧/微帧的时间内,可以通过总线进行数据传输的操作,如果没有数据传输操作需要执行,USB总线就会进入空闲状态,等这帧/微帧过后,USB总线的使用权会交给其他USB从机,周而复始。帧/微帧的间隔足够小,数据传输的操作就会频繁的在多个USB从机之间切换,看起来就好像是同时在进行数据传输一样
USB数据传输的最基本单位是包,由域可以组成包,而包可以组成事务,最终由事务可以组成传输
域是组成包的基本单位,本质上就是字段,或者说某段有意义的二进制数据。域总共有:
同步域的特殊含义
同步域之所以使用那么多0+1组成同步域,是因为USB通过NRZI(Non-Return-Zero Inverted 非归零码翻转)编码方式来表示电信号,NRZI编码的特点就是,无论当前收到的数据是0或1的话,那么下次如果收到数据1,电信号的极性保持不变,如果下次收到数据0,电信号的极性发生反转,这样的话如果传输连续的0就会导致信号一直发生反转,表现为一个方波。当信号接收方收到这个同步域信号时,会根据连续0的方波频率(发送方时钟频率),对自身时钟进行调节,最后的1用于表明同步域的结束,这就是同步域的作用
NRZI编码方式的缺点
不具备自同步性和连续信号1的识别是NRZI编码方式的缺点。不具备自同步表现在数据收发双方不能通过信号同步时钟信号,但是可以通过其他巧妙的方式解决此问题,例如USB的同步域。连续信号1的问题表现在,如果需要发送连续的信号1,那么信号的极性会很久都不会翻转,时间过长的话会导致数据收发双方时钟不同步,从而造成数据解析错误,例如会将原本100个1解析成99个1,为了解决这种问题,USB使用了位填充(bits-stuffing)的方式,对于连续7位的1,会在第6个1后强制插入0,使得电平强制发生翻转,以实现信号同步
包由域组成,但并不是所有的域都必须出现在包中(SYNC域和EOP域除外,它们代表着包的开始和结束),不同类型的包由不同的域组成
令牌包用于表明要开启一次USB数据传输。由于USB总线系统是主从结构的,所以无论是数据输入还是数据输出,都是由USB主机向USB从机发送令牌包,表明要进行数据传输。令牌包有以下4种:
其中OUT,IN,SETUP令牌包的组成都为
SOF令牌包的组成为
数据包很显然就是用来传输数据的,数据包的构成为
其中DATA域部分可以有0-1024个字节,用于装载要传输的数据。CRC域的长度位16位
由上述对DATA域的说明可以知道,USB1.X协议中数据包分为DATA0,DATA1两种类型,这两种类型数据包通过包类型切换机制可以加强数据包连续传输的可靠性,USB2.0规定了DATA2,MDATA两种类型,这两种类型的数据包主要用在高速分裂事务和高速高带宽同步传输中
通过包类型切换机制可以加强数据包连续传输的可靠性,其原理是,假设当前正在连续传输数据包,而当前传输数据包的包类型为DATA0,USB主机和从机都会通过自身的数据包标记记录当前的包类型DATA0,当前数据包如果传输成功,那么USB主机和从机都会将标记切换为DATA1,但是一旦当前数据包传输失败,例如USB从机接收到的数据不完整,那么USB从机中的数据包标记会保持DATA0不变,而USB主机由于已经完成数据发送操作,会将下次要发送的数据包以DATA1类型进行发送,USB从机匹配DATA1数据包标记发现和自身的DATA0数据包标记标记不匹配,会要求USB主机将上次的数据重新再发送,USB主机收到信号后会执行重传操作,以确保之前的DATA0数据包被正确传输
所有的连续数据包的类型都会在DATA0和DATA1之间不断翻转,以确保数据包准确传输
握手包用于确认一次USB数据传输的传输结果。握手包的组成很简单:
握手包表达的传输结果有4种,分别是:
注意:NAK握手包并不表示数据传输错误。当发生数据传输错误时,一种情况是会发生重传,另一种是USB主机,USB从机什么都不做,直到等待接收握手包的一方收不到握手包而等待超时
特殊包主要指的是一些在特殊场合才会使用的包,分为4种,分别为:
虽然包是USB数据传输的基本单位,但是并不能随意使用包来传输数据。必须按照一定的关系将不同的包组织成事务后,才能进行数据传输
事务就是由数据包的有序集合,一个事务可以由一个令牌包,若干可选的数据包,若干可选握手包,若干可选特殊包组成。事务按照不同的数据包组合,分为3类,分别是:
表示USB主机要从总线上某个USB从机接受一个数据包的过程,IN事务分为三个阶段:
表示USB主机要向总线上某个USB从机发送一个数据包的过程,OUT事务分为三个阶段:
其中SETUP事务和OUT事务的流程除了使用不一样的令牌包外,几乎是一样的,但SETUP事务是一种更特殊的USB事务,主要用于初始化设备,查询设备状态,配置设备等,SETUP事务分为三个阶段:
传输是为了适应不同的USB从机传输需求而诞生的,由多个事务组合而成
批量传输由IN/OUT事务组成。一般用于大批量,非实时的数据传输,换句话说就是传输的数据量大,对时间要求不高。例如USB存储设备,USB扫描仪等
批量传输属于可靠传输,因为在进行数据传输时,不仅会通过握手包确认传输结果,还通过数据包的包类型切换确保数据正确传输,同时在硬件级别还有执行“错误检测”和“重传”
批量传输模式中,每帧会尽可能的占用总线带宽,可以传输尽量多的IN/OUT事务
中断传输由IN/OUT事务组成。一般用于小批量,非连续的数据传输,换句话说就是传输的数据量小,数据不连续,实时性要求高。例如USB鼠标,USB键盘等
中断传输是保证频率的传输,中断端点需要在它的端点描述符中报告它的查询时间,主机会保证在小于这个时间间隔之内安排一次传输。中断传输中的中断,并不是硬件概念上的中断,而是主机主动发起传输的一种策略
中断传输模式中,每帧占用的带宽不确定,但最多只能传输1个IN或OUT事务
等时传输也被称为“同步传输”,由IN/OUT事务组成,一般用于要求数据量大,数据连续,实时性要求高的数据传输。这种传输对于时延非常敏感。例如USB摄像头,USB麦克风等
等时传输属于不可靠传输,传输流程没有握手包确认,没有包类型切换机制,也不支持重传。所以数据传输不保证100%正确,数据发送端只负责发送数据,不会去理会发送出去的数据包是否被搜到,数据接收端也不通过握手包确认数据,而是通过数据包中的16位CRC域进行校验,数据出错的后续处理由软件来定义
等时传输模式中,每帧占用的带宽是固定的
相对于其他传输方式,控制传输是比较特殊的,由SETUP/IN/OUT事务组成。它用于设备枚举时的设备信息获取或者设备配置。总共分为三个阶段:配置阶段,数据阶段(可选),状态阶段
配置阶段由一个SETUP事务组成,USB主机发起的SETUP事务,主要是通知从机即将获取信息/配置数据,USB从机只能接受SETUP事务,不能拒绝
数据阶段是可选的,由IN或OUT事务组成, 多组数据可以通过多组IN或OUT事务传输,但数据阶段传输只能传输一种数据类型,非IN即OUT。根据数据传输的有无和数据传输方向,数据阶段分为三种类型:
状态阶段主要用于反应整个控制传输的结果,由一个IN或OUT事务。至于是IN还是OUT事务,由数据阶段的事务类型决定,状态阶段的事务类型保持和数据阶段相反,数据阶段IN-状态阶段OUT,数据阶段OUT-状态阶段IN,其中事务的数据包类型必定为为DATA1,且数据长度为0
USB从机可以实现的功能多种多样,当从机接入总线时,主机要如何识别从机,配置从机呢?
这就需要USB描述符来实现,可以把USB描述符当作是USB从机的身份证,描述USB从机基本信息和配置等的数据结构,它通常存储在USB从机的非易失性存储器中。USB主机通过枚举,获取USB从机的描述符,从而取得USB从机的基本信息
USB从机接入主机后,主机识别并配置从机的流程被称为枚举。当USB从机连接到USB总线上时,USB主机会检测有USB从机插入,同时USB从机通电并将USB描述符信息从非易失性存储器加载到描述符寄存器中,等到USB主机从寄存器中获取到USB描述符,其中包括设备描述符,配置描述符,接口描述符,接口描述符。根据各个描述符就能知道USB从机的基本信息,完成配之后主机给从机分配对应的设备地址
USB描述符分为设备描述符,配置描述符,接口描述符,端点描述符,它们具体描述了以下信息:
USB从机有且只有一个设备描述符,主要用于记录设备的基本信息,包括设备包含的配置数量,设备使用的USB协议版本,设备类型,设备版本号,设备序列索引,厂商ID(VID),产品ID(PID),厂商字符串索引,产品字符串索引,端点0的最大包长等
设备描述符可以理解为USB从机的身份标识,直接对应着USB从机这个实体
USB从机一个设备描述符下可以包含多个配置描述符,主要记录了设备配置包含的接口数量,配置的编号,供电方式,电流需求量,是否支持远程唤醒等
配置描述符使得USB从机可以通过切换配置进行功能的切换,一个实体搭配不同配置,灵活使用
USB从机每个个配置描述符下会包含多个接口描述符,主要记录了接口号,接口的端点数,接口使用的类,子类和协议等
接口描述符主要是为了封装端点描述符而存在的抽象概念,可以理解为端点组合
USB从机每个接口描述符下会包含多个端点描述符,主要记录了端点的端点号,数据传输方向,数据传输类型,最大包长度,查询时间间隔等
综合上面对于描述符的介绍,描述符之间是存在层次关系的,如下图,最上层是设备描述符,接着分别是配置描述符,接口描述符,端点描述符。这意味着一个USB从机,可以拥有多种配置,而每种配置都会拥有一些接口,这些接口封装了很多端点,每个端点都用于数据传输,在需要时USB从机可以根据配置切换USB功能,USB主机会根据不同配置包含的端点信息,选择不同的信息传输方式,从而更方便的实现更多的功能。例如一个USB立体声音响,它有哪些具体端点我们可以不用去细究,但在接口描述符中拥有左声道,右声道接口,配置描述符上有单独左声道配置,单独右声道配置,立体声配置,通过切换不同的配置,可以实现音响的不同播放模式
从STM32的官方选型手册可以看出,部分型号的芯片支持USB-FS功能的,具体可以通过将GPIO复用为USB实现。为了支持USB-FS功能,STM官方提供了标准的USB-FS官方库(注意:不可商用)。
库的基本结构分为三层,分别是
具体层次关系如下图
库的数据处理流程需要结合USB标准协议中的内容去分析,可以分为
两个阶段的流程上很相似,具体如下:
端点0专门用于传输设备控制相关的信息;其他端点主要用于传输具体应用的信息,取决于USB从机的用途