1. USB协议
1.1 Packets
USB总线上数据传输以包为基本单位,一个包含不同的域,但都要从同步域开始,然后跟踪一个包标识符PID(Packet Identifier),最终以包结束符EOP(End of Packet)来结束这个包。
1.1.1 同步域
是以一串0开始的,作用是相当于uart的start信号。
1.1.2 包结束符EOP
对于全速、低速设备是一个大约为2个数据位宽的单端0(SE0)信号。SE0是指,D+和D-同时都保持为低电平。SE0用来表示一些特殊的含义,比如包结束、复位信号等。集线器就是通过将总线设置为SE0约为10ms实现设备复位。对于高速设备的EOP则是故意使用位填充错误来表示,如果CRC校验正确说明位填充错误是EOP,否则是传输出错。
1.1.3 包标识符PID
用来标识一个包的类型。共有8位,使用低4位,高4位取反用来校验PID。定义如下:
1.1.4 令牌包
令牌包用来启动一次USB传输,分别为:
- OUT,用来通知设备将要输出一个数据包
- IN,通知设备返回一个数据包
- SETUP,只用在控制传输中,和OUT作用一样,但是SETUP只能使用DATA0数据包,且只能发送到设备的控制端点,设备必须接收,而OUT令牌没有这些限制。
- SOF,帧起始包在每帧(或微帧)开始时发送,所有USB全速和高速设备都可以收到SOF包。全速设备每ms产生一个帧,高速设备每125us产生一个微帧。主机会对当前帧进行编号,每ms内的8个微帧编号相同。
每个令牌包,最后都有一个CRC5的校验,它只校验PID之后的数据,不包括PID本身。
图1.9.3 是OUT、IN、SETUP令牌包的结构。7位地址,按照A0、A1, ..., A6的顺序传输,最多支持125个设备。
1.1.5 数据包
在USB1.1协议中只有两种数据包:DATA0、DATA1包,在USB2.0又加入了DATA2和MDATA包,主要用在高速分裂事物和高速高带宽同步传输中。
不同的种类的数据包是用来当握手包出错时进行纠正,比如:当检测到对方使用的数据包类型不对时,一般发生在握手包被损坏的情况下,当一端正确接收数据并返回确认信号时,确认信号却受损。这时,另一端就无法得知刚刚发送的数据是否已成功,这时只好保持自己的数据包类型不变。如果对方下次用的数据包类型和自己的不一样说明刚刚成功接收到数据报了,因为进行了数据包类型的切换;如果下次收到的数据包类型和自己一致说明上次数据包没有发送成功,这是上一次的重试操作。
1.1.6 握手包
用来表示一个传输是否被对方确认,是最简单的一种数据包:
握手包有:
- ACK,表示正确接收数据,并有足够的空间容纳数据。主机、设备均可使用,但NAK、STALL、NYET只有设备可以用。
- NAK,表示没有数据需要返回,或者数据正确接收但是没有足够空间容纳它们。主机会以后重试。
- STALL,表示设备无法执行这个请求,或者端点已经被挂起了,表示错误状态。这时需要主机进行干预才能接触该状态。
- NYET,只在USB2.0的高速设备输出事务中使用,表示设备本次成功接收,但没有足够空间接收下次数据。主机下次输出数据会先用ping令牌试探设备是否有足够空间接收数据。
当主机或者设备检测到数据出错时(如CRC、PID校验错误,位填充错误等)将什么也不返回,这时等待接收握手包的一方就会收不到握手包从而等待超时。
1.1.7 特殊包
PRE,PING,SPLIT是令牌包,USB2.0协议新增,ERR是握手包。
- PRE,是通知集线器打开其低速端口的一种前导包。
- PING,和OUT令牌包有一样的结构,但是PING令牌包不发送数据而是等待设备返回ACK或者NAK,也判断是否能够传输数据。
- SPLIT,是高速事务分裂令牌包,通知集线器将高速数据包转换为全速或者低速数据包发送给其下面的端口。
- ERR,用来在分裂事务中表示错误。
1.1.8 如何处理数据包
一般USB接口芯片会自动完成如CRC校验、位填充、PID识别、数据包切换、握手等协议的处理。
当正确接收到数据时,如有空间存储,则会保存并返回ACK,同时置一个标志表示以正确接收到数据;如果没有空间存储,则自动返回NAK。
当收到输入请求时,有数据发送就发送数据,并等待接收ACK。只有当收到ACK之后,才置位表示成功发送;如果无数据发送,则自动返回NAK。
1.2 USB事务:四种传输类型
1.2.1 批量传输
包括三个阶段:令牌包阶段、数据包阶段、握手包阶段。流程如下图:
1.2.2 中断传输
要求主机保证不超过某个时间间隔安排一次传输,通常用在数据量不大,但是对时间要求较严格的设备中,如鼠、键盘等。 中断传输也可以用来不断检测某个状态,当条件满足后用来传输大量数据。
中断传输和批量传输类型,没有PING和NYET两种包,使用中断事务的流程图如下:
1.2.3 等时传输
用在数据量大、实时性高的场合如:音频和视频设备等,不要求数据100%正确,要保证不能停顿。
1.2.4 控制传输
分为三个过程:建立过程、可选的数据过程、状态过程。
- 建立过程使用一个建立事务,是一个输出事务和批量传输的输出事务不同:首先令牌使用SETUP,其次数据包只能用DATA0,最后握手包只能用ACK应答(除非错了,不应答),不能用NAK或者STALL来应答,即设备必须接收建立事务的数据。
- 数据过程是可选的。在数据过程中,所有的数据事务必须是统一方向的,一旦数据传输方向发生改变说明进入了状态过程。数据过程第一个数据包必须是DATA1包,然后依次切换。
- 状态过程,传输方向与数据过程相反。
1.3 端点类型及传输类型的关系
一个具体的端点(Endpoint)只能工作在一种传输模式下,通常我们把工作在什么模式下的端点就叫做什么端点。例如:控制端点、批量端点等。
端点0,是每个USB设备都必须举报的默认控制点,一上电就存在并且可以使用。其他端点是可选的,且只有在SetConfig之后才能使用。
每个端点描述符中都规定了端点所支持的最大数据包长。主机每次发送数据包,都不能超过端点的最大包长。
- 控制传输的端点,低速模式最大包长固定为8字节,高速模式最大包长固定64字节,而全速模式可在8、16、32、64字节中选择。
- 等时传输的端点,全速模式最大包长上限为1023字节,高速模式下包长最大上限为1024字节,低速模式下不支持等时传输。
- 中断传输的端点,低速模式最大包长固定为8字节,高速模式最大包长固定64字节,而全速模式可在8、16、32、64字节中选择。
- 批量传输的端点,高速模式包长固定为512字节,全速模式最大包长可在8、16、32、64字节中选择,低速模式不支持批量传输。
1.4 设备(device)、接口(Interfface)、端点(Endpoint)、管道(Pipe)等概念
层次概念
在USB设备的逻辑组织中,包含设备、配置、接口和端点4个层次,如下图:
每个USB设备都提供了不同级别的配置,可以包含一个或多个配置,一般一个配置为多。不同配置决定了不同的使用功能,配置由多个接口组成。比如USB音响可以用作音响也可以做读卡器使用,即具备不同的配置。
在USB协议中,接口由多个端点组成,代表一个基本的功能,是USB设备驱动程序控制的对象,一个功能赋值的USB设备可以有多个接口。比如USB音响可以包含一个音频接口和一个对旋钮和按钮的接口。
端点是USB通信的最基本形式,每一个USB设备接口在主机看来是一个端点的集合。主机只能通过端点与设备进行通信,从而使用设备的功能。每个端点都有唯一的地址,是由设备地址和端点号给出的。每个端点都有一定的属性,包括传输方式、总线访问频率、带宽、端口号和数据包最大容量等。一个USB端点只能在一个方向上承载数据(这是因为主机发送地址时,最高位D7表示读写位,1为Input,0为Output由此造成了某一个端点不可能同时为输入或是输出端点,只能是其一),因此端点可以看作是一个单向的通道。端点0通常作为控制端点,用于设备的初始化,其他端点作为数据端点用于主机与设备通信。
管道通信
端点就是通信的发送点或者接收点,主机使用设备的过程本质上就是主机缓冲区与端点进行数据交互的过程。需要往主机发送数据需要将数据放置到相应的输入端点,接收数据亦然。然而,这里涉及一个问题,就是数据怎么传?
- Stream形式,这个好理解,就是主机和设备无需解码,数据用户自定义。
- Message形式,这个数据是要有一定的通信格式的,我们在端点设置时曾涉及到它的通信协议,就是要符合相应的通信协议,也是为了方便使用标准驱动。
1.5 USB 信号