USB 协议学习:000-有关概念
背景
USB作为一种串行接口,应用非常广泛。掌握usb也是作为嵌入式工程师的一项具体要求。
概述
USB( Universal Serial Bus, 通用串行总线 )属于一种轮询式总线,主机控制端口初始化所有的数据传输。每一总线动作最多传送三个数据包,包括令牌(Token)、数据(Data)、联络(HandShake)。
按照传输前制定好的原则,在每次传送开始时,主机送一个描述传输动作的种类、方向、USB设备地址和终端号的USB数据包,这个数据包通常被称为令牌包(TokenPacket)。USB设备从解码后的数据包的适当位置取出属于自己的数据。数据传输方向不是从主机)到设备就是从设备到主机。
在传输开始时,由标志包来标志数据的传输方向,然后发送端开始发送包含信息的数据包或表明没有数据传送。接收端也要相应发送一个握手的数据包表明是否传送成功。发送端和接收端之间的USB数据传输,在主机和设备的端口之间,可视为一个通道。USB中有一个特殊的通道一缺省控制通道,它属于消息通道,设备一启动即存在,从而为设备的设置、状态查询和输入控制信息提供一个入口。
由于USB是主从模式的结构,设备与设备之间、主机与主机之间不能互连,为解决这个问题,扩大USB的应用范围,出现了USB OTG(ON The Go)。USB OTG 同一个设备,在不同的场合下可行在主机和从机之间切换。
USB 的 3种工作模式:低速(low speed)、全速(full speed)、高速(high speed)
在USB的通讯中,有传输(transfer),事务(Transaction),包(packet)三级。包是最基础的传输单元,与TCP/IP协议中的MAC层协议作用相同。
USB数据是由二进制数字串构成的,数字串构成域,域再构成包,包再构成事务(IN、OUT、SETUP),事务最后构成传输( 中断 interrupt 传输、并行传输、批量传输和控制 control 传输)。
域:若干个二进制数据组在一起叫做‘域’ 。
USB的域就是放在USB包中某小段某小段的数据。实际上我们以前的学习已经遇到了,只是没有这么叫。将域单独拎出来总结我认为对于初学者来说是比较混乱的。
- 在USB的通讯中,有传输(transfer),事务(Transaction),包(packet)三级。包是最基础的传输单元,与TCP/IP协议中的MAC层协议作用相同。
- 在一次传输中,由多次事务组成,每次的事务又由多个包组成
- 与众多协议相同,较高级别的协议的报文是基于/内嵌在低级协议的报文当中的,在USB中也不例外,例如,包中预留了DATA位,其目的就是填写报文
通信有关
一个设备有多个配置,一个配置有多个接口,一个接口有多个端点。(一个device有多个configuration,一个configuration有多个interface,一个interface有多个endpoint)
同一时刻只有一个配置有效;当我们需要不同的功能,只要选择不同的配置即可。同一个端点号不能出现在多个不同的接口中。
端点: 位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据,每一个端点都有唯一的确定地址,有不同的传输特性(如输入端点、输出端点、配置端点、批量传输端点)
帧: 时间概念,在USB中,一帧就是1MS,它是一个独立的单元,包含了一系列总线动作,USB将1帧分为好几份,每一份是一个USB的传输动作。
upstream、downstream(上行、下行):设备到主机为上行,主机到设备为下行
USB接口一般是4根线,VCC GND DM(D-) DP(D+) ;差分传输,3.3v 电压
传送方式: 数据在usb线里由地位到高位传送
枚举:USB主机检测到USB设备以后,读取设备的各种描述符的过程。
通过枚举,USB主机可以知道设备是什么样的设备,以对应加载合适的驱动程序。
调试USB设备,很重要的一点就是USB的枚举过程;只要枚举成功了,剩下的工作就不多了。
获取设备描述符的传输过程
设置事务:主机向设备下发 -> 80 06 00 01 00 00 40 00
- 令牌包 --> :SETUP类型
- 数据包 --> :由于令牌是SETUP类型,所以主机紧接着下发数据包,DATA0类型
- 握手包 <-- :设备收到数据包,回复应答
输入事务:设备向主机上发 -> 12 01 00 01 DC 00 00 10 71 04 F0 FF 00 01 00 00
- 令牌包 --> :IN类型,主机准备好,设备可以上发数据
- 数据包 <-- :DATA1类型:DATA0与DATA1在发送数据时需要交替,DATA中夹带设备描述符
- 握手包 --> :主机收到回复,向设备应答
输出事务:无
- 令牌包 --> :OUT类型
- 数据包 --> :DATA0类型,再一次切换为DATA0,没有需要发送给设备的
- 握手包 <-- :设备收到数据包,回复应答
USB的包
包:有四种类型,分别是令牌包、数据包、握手包和特殊包,不同的包的域结构不同,介绍如下:
1、令牌包:可分为输令牌入包(IN)、输出令牌包(OUT)、设置令牌包(SETUP)和帧起始包(SOF)(注意这里的输入包是用于设置输入命令的,输出包是用来设置输出命令的,而不是放据数的)其中输入包、输出包和设置包的格式都是一样的:SYNC+PID+ADDR+ENDP+CRC5(五位的校验码)
- 输出令牌包:用来通知设备将要输出一个数据包。
- 输入令牌包:用来通知设备符合一个数据包。
- 建立令牌包:只用在控制传输中,与输出令牌包作用相同。区别在于:SETUP令牌包以后只使用DATA0数据包,且只能发送到设备的控制端点且设备必须要接收;而OUT令牌包没有这些限制。
- 帧起始包:在每一帧/微帧开始时发送,以广播的形式发送给总线,所有的USB全速设备和高速设备都可以接收到(全速设备每毫秒发一个帧;高速设备每125us产生一个微帧);USB主机会对当前帧号进行计数,在每一帧开始时(或者微帧开始时,因为每毫秒有8个微帧,所以这8个微帧的帧号相同);帧号为11位。在4个令牌包中,只有SOF包之后不跟随数据传输(其他都有数据传输)。每一个令牌包都会有一个CRC5的校验。(只校验PID之后的数据,因为PID已经有4位反码进行校验了)
帧起始包的格式:
SYNC+PID+11位FRAM+CRC5(五位的校验码)+EOP
2、数据包:分为DATA0包和DATA1包,当USB发送数据的时候,当一次发送的数据长度大于相应端点的容量时,就需要把数据包分为好几个包,分批发送,DATA0包和DATA1包交替发送,即如果第一个数据包是 DATA0,那第二个数据包就是DATA1。但也有例外情况,在同步传输中(四类传输类型中之一),所有的数据包都是为DATA0,格式如下:
SYNC+PID+0~1023字节+CRC16
3、握手包:结构最为简单的包,格式:SYNC+PID
4、特殊包:根据不同的通讯而有不同的行为。schips
USB的事务
分别有IN(输入)、OUT(输出)和SETUP(设置)三大事务,每一种事务都由令牌包、数据包、握手包三个阶段构成。
USB事务的特点:
-
不能中断:USB的每次事务是“堵塞”,必须该事务完整后才能做其他事务
-
状态判断:之前的举例当中,每次传输都是成功的回复了ACK,可以看到,上图中,事务发起了三次IN的Token包,设备才发送了下一帧数据。不会因为设备忙就退出事务。
-
流程控制: 下发/接收数据、控制进出方向、确认回复
事务的三个阶段:
这里用阶段的意思是因为这些包的发送是有一定的时间先后顺序的。因为USB是半双工,DM DP并非独立工作,所以采用"三段式"通讯,保证总线不会冲突
1、令牌包阶段:主机发起,启动一个输入、输出或设置的事务。
2、数据包阶段:根据令牌包中的方向,由主机发起(OUT/SETUP)或者设备发起(IN)数据包。
3、握手包阶段:数据包接收方发起握手包,返回状态,包含ACK NAK STALL状态等。(在同步传输的IN和OUT事务中没有这个阶段)
事务的三种类型如下(以下按三个阶段来说明一个事务):
IN事务
令牌包阶段:主机发送一个PID为IN的输入包给设备,通知设备要往主机发送数据;
数据包阶段:设备根据情况会作出三种反应(要注意:数据包阶段也不总是传送数据的,根据传输情况还会提前进入握手包阶段)。
-
设备端点正常:设备往主机里面发出数据包(DATA0与DATA1交替);
-
设备正在忙:无法往主机发出数据包就发送NAK无效包,IN事务提前结束,到了下一个IN事务才继续;
-
相应设备端点被禁止:发送错误包STALL包,事务也就提前结束了,总线进入空闲状态。
握手包阶段:主机正确接收到数据之后就会向设备发送ACK包。
OUT事务
令牌包阶段:主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;
数据包阶段:比较简单,就是主机会往设备送数据,DATA0与DATA1交替
握手包阶段:设备根据情况会作出三种反应
-
设备端点接收正确,设备给主机返回ACK,通知主机可以发送新的数据,如果数据包发生了CRC校验错误,将不返回任何握手信息;
-
设备正在忙,无法给主机返回ACK,就发送NAK无效包,通知主机再次发送数据;
-
相应设备端点被禁止,发送错误包STALL包,事务提前结束,总线直接进入空闲状态。
SETUT事务
令牌包阶段:主机发送一个PID为SETUP的输出包给设备,通知设备要接收数据;
数据包阶段:比较简单,就是主机往设备送数据,注意,这里只有一个固定为8个字节的DATA0包,这8个字节的内容就是标准的USB设备请求命令,详见2.4。
握手包阶段:设备接收到主机的命令信息后,返回ACK,此后总线进入空闲状态,并准备下一个传输(在SETUP事务后通常是一个IN或OUT事务构成的传输)。
枚举过程
- 等待稳定:主机通过电平差检测到设备,等待100ms让设备电平趋于稳定
- 首次复位:HUB发起复位,让设备进入初始的地址0模式
- 首次查询设备描述符:GET_DESCRIPTOR 主机查询设备描述符,只要前8字节 ==>
80 06 01 00 00 00 12 00
- 二次复位:在接收到设备描述符前8个字节后,再次重启设备
- 设置地址:SET_ADDRESS 主机下发设置地址命令,设备获取新地址 ==>
00 05 01 00 00 00 00 00
- 二次查询设备描述符:GET_DEVICE_DESCRPTOR获取整个18字节的设备描述符 ==>
80 06 01 00 00 00 12 00
- 获取配置描述符:GET_CONFIGURATION 获取9字节配置描述符 ==>
80 06 02 00 00 00 09 00
- 完成配置:SET_CONFIGURATION,
附录: USB插入检测
- A:USB是如何检测到设备插入的
- Q:主机端将DM DP接入下拉电阻;设备端根据不同速度,将DM DP的某一根接上拉电阻,插入时通过压差即可判定是否插入
- 低速设备:在DM线上接入上拉
- 全速设备:在DP线上接入上拉
- 高速设备:在DP线上接入上拉,在主机对设备进行复位后进一步的确认
主机在要和设备通信之前会发送Reset信号(拉低两根信号线并保持10ms )来把设备设置到默认的未配置状态。