深入理解USB协议中的总线、接口、端点、管道和数据包枚举

目录

  • 简介
  • 背景
  • 特点
  • 版本
  • 数据流模型
  • 总线拓扑结构
  • 主/从设备通信流
  • 端点
  • 管道
  • 物理层
  • 接口类型
  • USB Type-A
  • USB Type-B
  • USB Type-C
  • 引脚定义
  • 4PIN
  • 9PIN
  • 5PIN
  • 24PIN
  • 16PIN
  • 6PIN
  • 电平标准
  • 协议层**
  • 通讯方式
  • 通讯方向
  • 同步方式
  • 帧和微帧
  • 数据格式
  • 令牌包
  • 数据包
  • 握手包
  • 特殊包
  • 事务
  • IN事务
  • OUT事务
  • SETUP事务
  • 传输
  • 批量传输
  • 中断传输
  • 等时传输
  • 控制传输
  • 配置阶段
  • 数据阶段(可选)
  • 状态阶段
  • USB描述符
  • 枚举流程
  • 设备描述符
  • 配置描述符
  • 接口描述符
  • 端点描述符
  • 描述符之间的关系
  • STM32_USB-FS-Device_Lib V4.1.0库分析
  • 层次关系
  • 传输流程
  • 简介

    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协议的目标,就是要解决以下+历史问题:

  • 支持热插拔:计算机无需关机即可同外设连接
  • 即插即用:在操作系统支持的情况下,会自行搜索并安装通用的设备驱动
  • 拓展性强:同时支持多种外设,例如鼠标,键盘,摄像头,打印机,麦克风等。开发者甚至可以自己定义外设
  • 支持多种传输速率:支持低速(1.5Mb/s),全速(12Mb/s),高速(480Mb//s),以及超高速(5Gb/s+)
  • 版本

    经过二十几年的发展,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总线系统是主从式结构的,它可以由一个主机和一个/多个从机构成:

  • 主机一般被称为Host,Host一般会有一个USB主控制器(用于处理数据传输)以及一个USB根集线器(用于同从机之间进行物理连接)
  • 从机一般被称为Device,一般就是指USB功能设备(发挥指定用途)或USB集线器(用于拓展USB接口)
  • 数据传输一般只能在主机和从机之间进行,主机与主机,从机与从机之间一般是不能进行数据交换的。

    USB OTG(On The Go)技术
    该技术在物理连接上多使用了一根ID数据线,用作身份标识。使用此技术的设备可以在主机和从机之间切换。例如支持USB OTG技术的手机,在连接计算机时可以当作从机,当使用专用数据线同USB设备连接时有又可以作为主机,可外接USB设备包括U盘,键盘等
    但从本质上讲,USB OTG技术依旧是遵循主从结构的

    数据传输是由主机进行主导的,从机只是被动地进行应答,无论是输入/输出数据,都是由主机端发起,从机收到主机的请求后,按照要求执行对应操作

    以下是USB总线系统的拓扑结构图:

    结合拓扑图,可以很好地理解USB总线系统的特点:

  • 整个系统以Host的根集线器为中心:这恰巧也诠释了USB主从模式的结构,主机是整个USB总线的中心
  • USB集线器最多可以串联5个:由于低层的集线器或从机进行数据传输时,都是共享的上一层集线器的带宽,过多的集线器串联会导致每个设备分配到的带宽变小。同时,过多的集线器串联可能会导致每个从机的供电量变小,不正常运行
  • 总线上最多能连接127个从机:USB协议规定,每个初始化成功的USB从机(USB功能设备和USB集线器)都必须有一个唯一的7位二进制地址,这就意味着理论上,单个USB根集线器下最多可以连接2^7=128个从机(除去特殊的地址0,地址0既是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从机都必须有一个控制端点:端点0,用于对设备进行枚举,以及对设备进行一些基本的控制。它的数据传输方向是双向的,而其他的普通端点的数据方向都是单向的
  • 普通端点:USB从机除了控制端点外,可以有一个或多个普通端点。低速从机做多可以有2个,高速和全速从机最多可以有15个。普通端点需要在设备配置之后才能进行数据传输
  • 管道

    管道是USB主机和USB从机之间数据传输的模型,共有两种类型的管道:

  • 无格式的流管道:数据从流管道的一端流进的顺序和从另一端流出的顺序是一样的(FIFO),流管道的通信流总是单向的
  • 有格式的信息管道:信息管道允许双方向的通信流,并且流过的信息为了确保可靠性都是带有格式的
  • 可以看出,管道的类型和端点的类型是有对应关系的:控制端点-信息管道/普通端点-流管道。值得注意的是,任何USB从机,在连接到总线后都会存在一个默认的信息管道,即控制管道,USB主机会通过这个管道获取USB从机设备的描述符(此处可以结合USB描述符的内容进行理解)

    物理层

    接口类型

    随着USB协议的不断更新,USB硬件接口的类型也不断迭代,常见的USB接口分别有USB Type-A,USB Type-B,USB Type-C这几个大类,每种接口都分有公头(插入)和母座(被插入),以下仅列出公头的图例:

    USB Type-A

    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 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 Type-C接口如今已经取代了很多的老旧接口,成为一种真正的通用型接口,这是由于其硬件规格上,支持更快的传输速率,更高的供电规格,更高的使用寿命,同时还有大众最喜欢的:支持正反插

    引脚定义

    USB通过硬件接口PIN脚上的差分信号传输数据,PIN脚的数量,在不同版本的USB协议以及不同类型的USB接口中都是不一样的

    差分信号是什么
    差分信号传输是一种常见的信号传输方式,它通过两根相反差分信号线之间电信号(电压或电流)的差值来表示数据。差分信号由于使用差值来表示数据,所以有很强的抗干扰能力,因为一旦出现信号影响的因素,虽然会造成两根信号线上的电信号波动,但是由于数据用电信号之间的差值表示,那么影响因素造成的电信号波动会相互抵消掉,从而实现数据的稳定传输

    4PIN

    USB2.0传输协议要求,硬件物理接口至少有4个PIN,4个PIN分别是:

  • D+:USB2.0差分信号正
  • D-:USB2.0差分信号负
  • GND:地线
  • VBUS:电源总线
  • 常见的标准USB Type-A接口,标准USB Type-B接口都是4个PIN脚的

    9PIN

    USB3.0传输协议由于对数据传输速率进行了提升,所以在USB2.0要求的硬件基础上,增加了超高速数据差分信号传输接口,所以共需要9个PIN脚。9个PIN分别是:

  • D+:USB2.0差分信号正
  • D-:USB2.0差分信号负
  • GND:地线
  • VBUS:电源总线
  • TX+:超高速差分信号TX正
  • TX-:超高速差分信号TX负
  • RX+:超高速差分信号RX正
  • RX-:超高速差分信号RX负
  • 常见的支持USB3.0传输协议的USB Type-A接口,是使用9个PIN脚的。此外从USB Type-A接口的 颜色上也能进行分辨,支持USB3.0传输协议的接口一般都有蓝色的塑料件

    5PIN

    5PIN的PIN脚数常见于USB Micro-A接口,USB Mini-A接口,USB Micro-B接口,USB Mini-B接口,其支持的协议依旧是USB2.0,多出的第5PIN,是为了支持USB OTG的功能,用作身份ID标识线。5个PIN分别是:

  • D+:USB2.0差分信号正
  • D-:USB2.0差分信号负
  • GND:地线
  • VBUS:电源总线
  • ID:身份标识线
  • 特别的是,USB Micro-B接口3.0版本是支持USB 3.0协议的,所以它的PIN脚比USB Micro-B接口普通版本要多,外形上也有很大改变,但似乎因为结构设计上不太合理,所以并没有被广泛使用,尤其是USB
    Type-C接口出现后

    24PIN

    24PIN的PIN脚数仅能用在USB Type-C接口上,因为支持正反插,所以实际上24个PIN脚对应的作用是有重复的。这24个PIN脚分别是:

  • 4 * VBUS:电源总线
  • 4 * GND:地线
  • 2 * D+:USB2.0差分信号正
  • 2 * D-:USB2.0差分信号负
  • 2 * TX+:超高速差分信号TX正
  • 2 * TX-:超高速差分信号TX负
  • 2 * RX+:超高速差分信号RX正
  • 2 * RX-:超高速差分信号RX负
  • CC1/CC2:协助PD快充协议进行设备识别
  • SUB1/SUB2:特定模式下传输辅助信号
  • 24PIN脚的USB Type-C接口又被称为全功能USB Type-C接口

    16PIN

    16PIN的PIN脚数其实是24PIN脚USB Type-C的阉割版,由于部分设备可能使用不到USB3.0的速度,所以可以把超高速差分信号相关的8个引脚去掉。这样的USB总线系统在硬件接口上使用USB Type-C接口,传输协议上就使用USB2.0传输协议。

    6PIN

    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数据传输的最基本单位是,由域可以组成,而包可以组成事务,最终由事务可以组成传输

    域是组成包的基本单位,本质上就是字段,或者说某段有意义的二进制数据。域总共有:

  • 同步域:用于同步USB主机和USB从机,对于低速,全速USB从机,同步域为00000001B(8位),对于高速USB从机,同步域为0000000000000000000000000000001B(32位)
  • 同步域的特殊含义
    同步域之所以使用那么多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,使得电平强制发生翻转,以实现信号同步

  • 包标识域:用于表明包的类型,数据包分为令牌包,数据包,握手包,特殊包。通过4位二进制表示,分别有以下类型:
  • 地址域:由设备地址域和端点地址域组成,设备地址用7位二进制表示,端点地址用4位二进制表示,通过地址域可以得到USB从机的设备地址,以及对应的端点地址,此后通过设备地址+端点地址,结合端点对应数据传输方向就能实现对设备端点(即数据传输的Buffer)的精准定位
  • 帧号域:用于标识数据传输中的帧号,以便同步USB主机和USB设备
  • 数据域:用于传输实际数据内容
  • CRC校验域:用于检查数据传输的正确性,CRC域的数据长度与数据域的长度有关
  • 包结束域:用于标识数据包的结尾,长度位1位二进制
  • 包由域组成,但并不是所有的域都必须出现在包中(SYNC域和EOP域除外,它们代表着包的开始和结束),不同类型的包由不同的域组成

    令牌包

    令牌包用于表明要开启一次USB数据传输。由于USB总线系统是主从结构的,所以无论是数据输入还是数据输出,都是由USB主机向USB从机发送令牌包,表明要进行数据传输。令牌包有以下4种:

  • OUT(输出):告知USB从机,USB主机即将要输出一个数据包
  • IN(输入):告知USB从机,USB主机需要从USB从机获取一个数据包
  • SETUP(建立):告知USB从机,USB主机即将要输出一个数据包,和OUT令牌包不同的是,SETUP令牌包会开启控制传输,USB主机之后将向从机发送一个DATA0类型(只能为此类型)数据包,数据包的目的地是USB从机的控制端点,此端点地址为0,USB从机必须接受此数据包
  • SOF(帧起始):表明这是一个帧起始包,帧起始包在每个帧开始时都会以广播的形式发送
  • 其中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种,分别是:

  • ACK(确认):表示数据接受正确,并且数据接收端有足够的空间容纳数据。USB主机和USB从机都可以使用ACK握手包确认
  • NAK(未确认):表示没有数据可以返回,或是数据传输正确,但是数据接收端没有足够空间接收,只有USB从机可以使用NAK握手包
  • STALL(挂起):表示USB从机无法执行这个请求,这是一种错误的状态,需要USB干预才可以解除。只有USB从机可以使用STALL握手包
  • NYET(未就绪):用于USB2.0数据传输的高速设备输出事务中,表示数据传输正确,但是数据接收端没有足够空间接收,USB主机下次传输数据时,会先使用PING特殊包试探是否可进行数据传输,只有USB从机可以使用NYET握手包
  • 注意:NAK握手包并不表示数据传输错误。当发生数据传输错误时,一种情况是会发生重传,另一种是USB主机,USB从机什么都不做,直到等待接收握手包的一方收不到握手包而等待超时

    特殊包

    特殊包主要指的是一些在特殊场合才会使用的包,分为4种,分别为:

  • PRE:是通知集线器打开其低速端口的前导令牌包。PRE只能用于全速传输模式中。平常为了防止全速信号使低速从机误动作,集线器是不会将全速信号信号传送给低速从机的。当集线器接收到此信号时,会将信号通过低速模式传给低速设备
  • ERR:是用于分裂事务中表示错误使用的握手包
  • SPLIT:是高速事务分裂令牌包,它会让集线器将高速数据包转化为全速或低速数据包下发给USB从机的端口
  • PING:和OUT令牌包一样结构的令牌包,但是他不传输数据,而是等待USB从机返回ACK或NAK握手包信号
  • 事务

    虽然包是USB数据传输的基本单位,但是并不能随意使用包来传输数据。必须按照一定的关系将不同的包组织成事务后,才能进行数据传输

    事务就是由数据包的有序集合,一个事务可以由一个令牌包,若干可选的数据包,若干可选握手包,若干可选特殊包组成。事务按照不同的数据包组合,分为3类,分别是:

    IN事务

    表示USB主机要从总线上某个USB从机接受一个数据包的过程,IN事务分为三个阶段:

  • 令牌包阶段:USB主机发送一个IN令牌包给USB从机,通知USB从机要向USB主机发送数据
  • 数据包阶段:USB设备根据自身状态,会有三种反应:USB设备确认无误,那么会返回数据包;USB设备正忙/出错,不返回数据包,直接跳转到下一阶段
  • 握手包阶段:USB主机正确接收数据会返回ACK握手包,如果USB设备正忙/出错,会返回NAK/STALL握手包给USB主机
  • OUT事务

    表示USB主机要向总线上某个USB从机发送一个数据包的过程,OUT事务分为三个阶段:

  • 令牌包阶段:USB主机发送一个OUT令牌包给USB从机,通知USB从机即将要接受USB主机发送的数据
  • 数据包阶段:USB主机会发送数据包
  • 握手包阶段:USB设备根据自身状态,会有三种反应:可以接收,那么会返回ACK握手包;USB设备正忙/出错,返回NAK/STALL握手包
  • SETUP事务

    其中SETUP事务和OUT事务的流程除了使用不一样的令牌包外,几乎是一样的,但SETUP事务是一种更特殊的USB事务,主要用于初始化设备,查询设备状态,配置设备等,SETUP事务分为三个阶段:

  • 令牌包阶段:USB主机发送一个SETUP令牌包给USB从机,通知USB从机即将要接受USB主机发送的数据
  • 数据包阶段:USB主机会发送数据包
  • 握手包阶段:USB设备根据自身状态,会有三种反应:可以接收,那么会返回ACK握手包;USB设备正忙/出错,返回NAK/STALL握手包
  • 传输

    传输是为了适应不同的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事务,可以看做是读取USB从机的基本信息
  • 控制写:即传输OUT事务,可以看作是配置USB从机的驱动或者基本信息
  • 无数据传输:不进行事务传输,有可能是因为传输的数据过少,已经通过配置阶段的SETUP事务完成数据传输
  • 状态阶段

    状态阶段主要用于反应整个控制传输的结果,由一个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描述符信息从非易失性存储器加载到描述符寄存器中,等到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-Device_Lib V4.1.0库分析

    从STM32的官方选型手册可以看出,部分型号的芯片支持USB-FS功能的,具体可以通过将GPIO复用为USB实现。为了支持USB-FS功能,STM官方提供了标准的USB-FS官方库(注意:不可商用)。

    层次关系

    库的基本结构分为三层,分别是

  • 应用层:实现USB设备相关的内容,包括配置描述符定义,标准请求定义,类特定请求定义,用户可按需求修改
  • 核心层:实现了USB标准中规定的内容,包括对控制传输的处理,标准类请求,获取配置描述符等
  • 硬件层:实现了对STM32上的USB专用寄存器的封装,USB中断数据的处理,USB数据包的传输
  • 具体层次关系如下图

    传输流程

    库的数据处理流程需要结合USB标准协议中的内容去分析,可以分为

  • 枚举阶段:主要是获取从机的USB描述符(设备,配置,接口,端点四种描述符),从而进行USB从机的配置
  • 数据传输阶段:USB主机根据枚举阶段对端点的配置,定时和USB从机进行通信进行,进行数据的交换(USB主机为主的发送或接受)
  • 两个阶段的流程上很相似,具体如下:

    1. 根据USB主机/从机交互是由USB主机来控制的,每次发起数据传输主机都会向从机发送数据。此时,会触发从机的USB硬件中断,从而通过中断向量表跳转到中断处理函数USB_LP_CAN1_RX0_IRQHandler
    2. 中断处理函数中会调用USB_Itsr函数,此函数和USB的ITSR寄存器(负责记录USB传输的状态信息的)相关,负责从ITSR寄存器中读取数据传输的端点号,进行相应传输:如果是端点0,那么进行端点0的控制传输。如果其他端点,那么进行用户定义的数据传输。两种阶段在这里会有不一样的处理方法
    3. 如果上一阶段请求数据传输是端点0,那么进入标准请求的处理,可能会获取配置描述符,或者是配置从机状态或特性(还需要依赖于从机是否支持这些功能),这部分内容在核心层的usb_int系列文件中被定义。如果上一阶段请求数据传输是其他端点,USB主机会根据端点描述符中的配置,读取/写入对应端点的数据缓冲区,缓冲区会被清空/配置数据,发生数据交换同时会调用用户配置的回调函数,这部分内容在应用层的usb_endp.c中定义

    端点0专门用于传输设备控制相关的信息;其他端点主要用于传输具体应用的信息,取决于USB从机的用途

    物联沃分享整理
    物联沃-IOTWORD物联网 » 深入理解USB协议中的总线、接口、端点、管道和数据包枚举

    发表评论