USB 协议数据包的层次结构和组成

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

前言

USB 的数据由 包(Packet) 组成 事务(Transaction) 事务组成 传输(Transfer)不同传输类型每 帧(Frame) 占用带宽的特性不同。

在这里插入图片描述


我们可以看到一个传输Transfer是可以拆分成事务Transaction的并且一个事务Transaction又可以拆分为包Packet。

在这里插入图片描述


一、包(Packet)

包的组成结构

包由以下几部分组成

  • 同步字段SYNC)
  • 包标识符字段(PID)
  • 设备地址和端点地址(ADDR)
  • 帧号(Frame Number)
  • 数据字段(DATA)
  • 循环冗余校验字段(CRC)
  • 结尾字段(EOP)

不同种类的 Packet 所含字段是上面字段的子集并不会包含所有的字段。

在这里插入图片描述


包的域格式

USB 总线上的数据传输是以包Packet为基本单位的。一个包被分成不同的域Filed也称为字段。根据不同类型的包所包含的域是不一样的。但是不同的包有一个共同的特点。就是都要以同步域SYNC开始紧跟着一个包标识符PIDPacket Identifiter最后以包结束符EOPEnd Of Pactet来结束这个包

所有数据包都以 同步SYNC字段 开始该字段是生成最大边缘过渡密度的编码序列。

在这里插入图片描述

下图为USB1.1设备的同步域数据包。

在这里插入图片描述


Packet 的分类及其构成

Packet 的分类

1. 令牌包 token
PID + ADDR(设备地址端点地址) + CRC5

2. 帧首包 SOF(Start of frame)
PID + 帧号 + CRC5

3. 数据包 DATA
PID + 数据 + CRC16

4. 握手包 Handshake
PID


相应的 PID 域的分类

  1. Token
    SETUP, IN, OUT, SOF

  2. Data
    DATA0, DATA1, DATA2, MDATA

  3. Handshake
    ACK, NAK, STALL, NYET

在这里插入图片描述


Packet 的构成

  1. 令牌包 token
    PID + ADDR(设备地址端点地址) + CRC5;

在这里插入图片描述

举例

在这里插入图片描述


  1. 帧首包 SOF(Start of frame)
    PID + 帧号 + CRC5;

在这里插入图片描述

举例
在这里插入图片描述


  1. 数据包 DATA
    PID + 数据 + CRC16;

  2. 握手包 Handshake
    PID;

举例数据包后面就跟随有握手包。

在这里插入图片描述


二、事务(Transaction)

在 USB 上数据信息的一次接收或发送的处理过程称为事务处理一个事务Transaction由若干个包Packet组成取决于具体的事务类型可能由以下包组成一个令牌包 token packet可选的数据包 data packet可选的握手包 handshake packet可选的特殊包 special packet

事务分为 3 类 SETUP 事务IN 事务和 OUT 事务如下所示

在这里插入图片描述


三、传输(Transfer)

用于描述端点(Endpoint)或通道(Pipe)的特性传输分为以下四类

  • 中断传输(Interrupt Transfer)
  • 控制传输(Control Transfer)
  • 同步传输(Isochronous Transfer)
  • 批量传输(Bulk Transfer)

同步传输每帧占用固定带宽
中断传输每帧都占用带宽但所占带宽不固定
控制传输和批量传输在需要时才占用帧带宽批量传输将会占用帧的所有剩余带宽。

除同步传输外一个事务Transaction由一个令牌包若干个数据包一个握手包构成。
而同步传输没有握手包所以接收端接收完同步传输数据包计算出 CRC即使发现数据有错也不能发送握手包给发送端让发送端重发。

一般而言一个 USB 中断完成一个事务Transaction令牌包和握手包的传输由硬件完成数据包由应用程序完成。


1. 控制传输(Control Transfer)

控制传输用于主机枚举设备时从设备获取信息或配置信息。

控制传输由 建立阶段(SETUP)数据阶段(DATA)状态阶段(STATUS) 组成。其中数据阶段是可选的数据阶段可以包含多个 IN 事务或 OUT 事务且在一次控制传输中只能包含 IN 事务或 OUT 事务不能既包含 IN 事务也包含 OUT 事务。状态阶段包含 1 个事务事务的方向一定跟数据阶段相反如果数据阶段包含 IN 事务那么状态阶段就会包含 OUT 事务反之亦然。如果没有数据阶段状态字段所包含的事务方向与建立阶段相反即包含 IN 事务。

在这里插入图片描述

可以看到控制传输Transfer包含的事务Transaction类型有SETUP 事务IN 事务和 OUT 事务


建立阶段(SETUP STAGE)

建立阶段由 1 个 SETUP 事务组成而 SETUP 事务由 PID 为 SETUP 的 token 包PID 为 DATA0 的 data 包PID 为 ACK/NAK/STALL 的 handshake 包组成。控制传输的建立阶段的 data 包用于主机给设备发送 请求(Request)相当于发送命令给设备。

在这里插入图片描述


数据阶段(DATA STAGE)

数据阶段是用来传输建立阶段的 请求(Request) 所跟随的数据的如果 1 个事务不能传输完所需数据就会分多个事务传输 根据请求里的 bmRquestType 字段数据阶段能获悉需要 IN 事务还是 OUT 事务为了确保没有丢失 data 包data 包的 PID 会不停地切换即 DATA0DATA1, DATA0…

状态阶段(STATUS STAGE)
状态阶段用来表示整个控制传输过程已经结束。状态阶段的 token 包的 PID 必定与数据阶段相反即数据阶段是 IN token包状态阶段就是 OUT token 包。

跟随其后的是数据域长度为 0 的 PID 为 DATA1 的数据包。最后是 handshake 包根据响应情况分为以下三类响应返回 ACK 包未响应返回 NAK 包不支持该请求返回 STALL 包。

举例

在这里插入图片描述

有的控制传输中无数据则在 SETUP 事务后面跟一个 IN 状态事务就可以。

在这里插入图片描述


2. 批量传输(Bulk Transfer)

用于传输突发的大量数据要求数据不能出错但对时间没有要求适用于存储设备、打印机等。

批量传输是可靠的传输需要握手包来表明传输的结果。若数据量比较大将采用多次批量事务传输来完成全部数据的传输传输过程中数据包的 PID 按照 DATA0-DATA1-DATA0-…的方式翻转以保证发送端和接收端的同步。

它通过在硬件级执行 “错误检测”和“重传” 来确保 host 与 device 之间“准确无误”地传输数据即可靠传输。

它由三种包组成(即 IN 事务或 OUT 事务)

  1. token 包
  2. data 包
  3. handshake 包

在这里插入图片描述

对于 IN Transaction
ACK表示 host 准确无误地接收到数据包
NAK表示 device 暂时不能返回数据如设备忙
STALL表示 device 拒绝了请求

对于 OUT Transaction
ACK表示 device 准确无误地接收到数据包
NAK表示 device 暂时不能接收数据如设备忙
STALL表示 device 端点已经停止且通知 host 不再重传

举例

在这里插入图片描述

上面列出了一个批量写传输和批量的读传输。

和控制传输相比就简单很多了只有数据传输没有SETUP事务和状态事务。

在事务中也分为三个阶段即令牌阶段令牌包、数据传输阶段数据包、握手阶段握手包。

当然上面这两个批量传输的数据很少分别是31和36个字节一个传输就传完了。

下面这个全速设备每次最多传输64字节传输4096个字节就需要很多个传输了。

在这里插入图片描述


3. 中断传输(Interrupt Transfer)

中断传输每一帧(Frame)最多 传输 1 次事务而批量传输可以在总线空闲时在帧内传输多次事务中断传输不支持 PING优先级更高最大包长与批量传输不同其他的与批量传输相同。主机在排定中断传输任务时会根据对应中断端点描述符中指定的查询间隔发起中断传输。中断传输有较高的优先级仅次于同步传输

中断传输是一种保证查询频率的传输。中断端点在端点描述符中要报告它的查询时间主机会保证在小于这个时间间隔的范围内安排一次传输。

这里所说的中断和我们硬件 CPU 上的中断是不一样的。他不是由设备主动的发出一个设备请求而是由主机保证不大于某个时间间隔内安排一次传输。 中断传输通常用在数据量不大但是对时间要求较严格的设备中例如人机接口设备HID中的鼠标键盘轨迹球。中断传输也可以用来不停的检查某个状态当条件满足后再用批量传输来传送大量的设备。除了对端点查询的策略上不一样之外中断传输和批量传输的结构基本上是一样的。只是中断传输中没有 PING 和 NYET 两种包。中断传输使用中断事务Interrupt Transactions。中断事务的流程图如下。

在这里插入图片描述

举例下图给出了 USB 鼠标在按键中断事务中一次输入传输。可以看到格式和批量传输是一样的。

在这里插入图片描述

举例2

在这里插入图片描述

上图给出了中断 IN 传输的数据过程。

在中断事务中也分为三个阶段即令牌阶段令牌包、数据传输阶段数据包有则返回数据没准备好则不返回数据、握手阶段握手包从机正常返回数据主机解析成功则主机给从机应答。从机没准备好数据则从机给主机返回 NAK。

可以看到主机对设备进行定期查询。

如果设备有数据则对 IN 事务进行响应返回数据主机解析成功数据返回 ACK 应答。

如果设备没数据则返回 NAK 表示没准备好数据。


4. 同步传输(Isochronous Transfer)

同步传输是不可靠传输它没有握手包也没有 PID 翻转不支持重传主机在安排事务传输时同步传输具有最高优先级。同步传输适用于固定速率抵达或指定时刻抵达的场合可以容忍偶然错误的数据上。一般用于喇叭麦克风摄像头等实时性要求高的设备。它由令牌包和数据包组成没有握手包

同步传输用在数据量大、对实时性要求高的场合例如音频设备、视屏设备等这些设备对数据延时敏感。对音频或者视屏设备来说对数据的100%正确要求不高少量数据的错误还是能够容忍的主要是要保证不能停顿所以同步传输是不保证数据100%正确的。当数据错误时并不能进行重传操作。因此同步传输也就没有应答包并不进行重传操作。数据是否正确可以由数据包的 CRC 校验来确认。至于出错的数据如何处理由软件来决定。同步传输使用同步事务Isochronous Transactions来传输数据。下图是同步事务的流程图。

在这里插入图片描述

暂时没同步传输的抓包信息就不分析了。只需要知道同步传输是没应答包的。其它和上面几种没大的差异。


四、请求(Request)

请求是控制传输中usb host 向 usb device 发送的用于配置属性发送数据或者接收数据的命令。

请求通过控制传输的 SETUP 事务的 DATA0 包发送出去。请求分为标准请求Standard Request和类特定请求(Class-Specified Request)USB 规范定义了 11 个标准请求它们分别是Clear_Feature、Get_Configuration、Get_Descriptor、Get_Interface、Get_Status、Set_Address、Set_Configuration、Set_Descriptor、Set_Interface、Set_Feature、Synch_Frame。所有 USB 设备都必须支持这些请求个别请求除外如Set_Descriptor、Synch_Frame。

主机负责建立表 9-2 中列出的字段中传递的值。 每个 Setup 数据包都有 8 个字节

如下图所示是 SETUP DATA 包的数据格式为 8 个字节。

在这里插入图片描述

在这里插入图片描述


1. bmRequestType(向谁请求)

D7传输方向

  • 0 = 主机至设备
  • 1 = 设备至主机

D6…5命令类型

  • D6D5=00标准请求命令;
  • D6D5=01类请求命令
  • D6D5=10用户定义命令
  • D6D5=11保留。

D4…0接受者类型

  • 0=设备
  • 1=接口
  • 2=端点
  • 3=其它
  • 4…31 保留

这个域表明此请求的特性。特别地这个域表明了第二阶段控制传输方向。如果 wLength 域被设作 0 的话表明没有数据传送阶段那 Direction 位就会被忽略.

USB 说明定义了一系列所有设备必须支持的标准请求。这些请求见下面的表。另外一个设备类可定义更多的请求。设备厂商也可定义设备支持的请求.

请求可被导引到设备设备接口或某一个设备端点(endpoint)上。这个请求域也指定了接收者。当指定的是接口或端结点(endpoint)时wIndex 域指出哪个接口或端节点。


2. bmRequest(什么请求)

这个域标识特别的请求。bmRequestType 域的 Type 字段可修改此域的含义。协议中仅定义 Type 字段为 0 即标准设备请求时 bRequest 域值的含义。

在这里插入图片描述


3. wValue 域

此域用来传送当前请求的参数随请求不同而变。


4. wIndex 域

该字段的内容根据请求而有所不同。它用于将参数传递给设备特定于请求。

当 bmRequestType 的 Recipient 字段为接口或端点时wIndex 域用来表明是哪一个接口或端结。

图 9-2 显示了用于指定端点时的wIndex格式。

在这里插入图片描述

Direction 位bit7设置为零以指示具有指定端点编号的 OUT 端点并指定一个以指示IN端点。 对于控制管道请求应将Direction 位设置为零但设备可以接受 Direction 位的任一值。

图 9-3 显示了用于指定接口时的 wIndex 格式.
在这里插入图片描述


5. wLength 域

这个域表明第二阶段的数据传输长度。传输方向由 bmRequstType 域的 Direction 位指出。wLength 域为0则表明无数据传输。在输入请求下设备返回的数据长度不应多于 wLength但可以少于。在输出请求下wLength 指出主机发出的确切数据量。如果主机发送多于 wLength 的数据设备做出的响应是无定义的。


6. 标准设备请求

本节介绍为所有 USB 设备定义的标准设备请求。 表 9-3 概述了标准设备请求而表 9-4 和表 9-5 分别给出了标准请求代码和描述符类型。

USB设备必须响应标准设备请求即使设备尚未分配地址或尚未配置。

在这里插入图片描述


7. 标准请求码bRequest的值

在这里插入图片描述


8. 描述符类型

在这里插入图片描述


下面说明几种常见的设备请求

1. 清除特性clear Feature

该请求时用来取消一个特性其格式如下
在这里插入图片描述

在这里插入图片描述

该请求中的 wVlaue 表示特性选择器它对应的值为0 = 端点1 = 设备。当某个特点不允许取消或者特性根本不存在或者是指向一个根本不存在的接口或端点时该请求将会导致设备请求失败如果一个端点被固件设置为停止状态主机软件也可以发送一个值为 0 的 CLEAR_FEATURE 命令清除该端点的停止状态。

2.获得描述符GetDescriptor

该请求可以获得 USB 设备中存在的特定的描述符其格式如下
在这里插入图片描述
在这里插入图片描述

该请求中的 wValue 的高字节表示要取的设备描述符低字节表示描述符的索引值描述的类型见上面 9-5 表。

wIndex 的值为 0 或语言 ID当要取的值为字符串描述符时该域的值为语言 ID当为其它的描述符时该域为 0。

wLength 表示要返回的数据长度如果 SETUP 阶段的地址使用的是预设地址 0ENDP 字段为 0这时 wLength 值会大于实际的描述的值。这是为什么 原因是用户预设的地址 0 来取得设备描述符时不管多少个字节用户最多只能取前 8 个字节即在控制传输过程只有一次数据阶段。但是如果用户新的地址ENDP字段不为0来取得设备描述符时。这时 wLength 的值就要注意了。

3.设置地址SetAddress

该请求给 USB 设备设置值地址从而可以对该 USB 设备进行下一步的访问其格式如下

在这里插入图片描述

该请求与其他请求有一个重要的不同点该请求下USB 设备一直不改变它的地址直到该请求的状态阶段被成功的完成而其他请求的操作都是在状态阶段之前完成。

4.设置配置SetConfiguration

该请求对设备进行设备值。其格式如下
在这里插入图片描述

该请求中的 wValue 域的低字节表示设置的值该值必须为 0 或者与配置描述符中的配置值相匹配。如果设置值等于 0表示设备在地址状态。如果 wIndex 或 wLength 为非 0 值那么该请求不执行。

5. 获得接口GetInterface

此请求返回指定接口的选定备用设置。

在这里插入图片描述

某些 USB 设备的配置具有互斥设置的接口。 此请求允许主机确定当前选择的备用设置。
如果 wValue 或 wLength 不是上面指定的则不指定设备行为。如果指定的接口不存在则设备将响应请求错误。

默认状态未指定在设备处于“默认”状态时收到此请求时的设备行为。
地址状态设备给出了请求错误响应。
已配置状态当设备处于已配置状态时这是一个有效请求

6. 获得状态Get State

在这里插入图片描述
bmRequestType 字段的 Recipient 位指定所需的收件人。 返回的数据是指定收件人的当前状态。
如果 wValue 或 wLength 不是上面指定的或者如果设备状态请求的 wIndex 不为零则不指定设备的行为。

如果指定的接口或端点不存在则设备将响应请求错误。

默认状态未指定在设备处于“默认”状态时收到此请求时的设备行为。
地址状态如果指定了端点0以外的接口或端点则设备将响应请求错误。
已配置状态如果指定了不存在的接口或端点则设备将响应请求错误。

对设备的GetStatus请求返回如图9-4所示的信息.

在这里插入图片描述

自供电字段指示设备当前是否为自供电。 如果D0复位为零则器件由总线供电。 如果D0设置为1则设备是自供电的。 SetFeature或ClearFeature请求不能更改Self Powered字段。

“远程唤醒”字段指示设备当前是否已启用以请求远程唤醒。 禁用支持远程唤醒的设备的默认模式。 如果D1复位为零则禁用设备发出远程唤醒信号的能力。 如果D1设置为1则启用设备发出远程唤醒信号的能力。 可以使用DEVICE_REMOTE_WAKEUP功能选择器通过SetFeature和ClearFeature请求修改远程唤醒字段。 器件复位时该字段复位为零。

对接口的GetStatus请求返回如图9-5所示的信息。
在这里插入图片描述

对端点的GetStatus请求返回如图9-6所示的信息。
在这里插入图片描述

结合上面的格式我们分析一下下面的 SETUP 令牌事务的作用。

在这里插入图片描述

结合前面的学习我们知道了host 发给 device 的数据 SETUP 数据是 HEX: 80 06 00 01 00 00 40 00.

第一个字节 0x80 拆分可以得到这是一个主机发给设备bit0 ~ bit4的一个标准bit5 ~ bit6的请求命令请求的结果是要求设备给 Host 返回bit7 == 1。
在这里插入图片描述

第二个字节 0x06 查看表 9-4 可以得到这是一个 GET_DESCRIPTOR即获取描述符的请求。

在这里插入图片描述

第三四字节传的是 0x0100 查看描述符表得知高字节表示描述符类型01表示设备02表示配置低字节表示索引。比如设备有多个配置那需要读取不同配置的时候就通过低字节。或者一个配置下有多个接口通过索引选择不同的接口。所以这里高字节的 1 代表设备低字节在本设备没用到。

在这里插入图片描述

在这里插入图片描述

第五六字节为 0x0这个参数如果为0则不关心如果为非零则表示Langurage ID每一位都有对应的意义。

在这里插入图片描述

第七八字节为 0x40即代表返回的数据不应该多于 64 字节。

在这里插入图片描述

分析总结该 SETUP 事务为主机获取从机的设备描述符。

接下来再看一个例子

在这里插入图片描述
结合前面的学习我们知道了host 发给 device 的数据 SETUP 数据是 HEX: 00 05 03 00 00 00 00 00 。

第一个字节 0x0这是一个主机发给设备bit0 ~ bit4的一个标准bit5~bit6的请求命令请求的结果是主机和设备发送bit7 == 0信息。
在这里插入图片描述

第二个字节 0x05从 table 9-4 可以看到SET_ADDRESS是主机给从机设置地址。

在这里插入图片描述

第三四个字节合起来是0x03对照标准的设备请求表可以知道这是就是主机给设备分配的设备地址 3。
在这里插入图片描述

第五六字节合起来是 0x0从标准的设备请求表可以看到这里没任何作用只是为了满足标准的 SETUP 令牌请求格式。

第七八字节同上。

在这里插入图片描述
分析总结该请求为主机给设备设置从机地址为 3。

接下来看最后一个例子

在这里插入图片描述

结合前面的学习我们知道了host 发给 device 的数据 SETUP 数据是 HEX: 80 06 02 03 09 04 FF 00 。

第一个字节 0x80这是一个主机发给设备bit0 ~ bit4的一个标准bit5~bit6的请求命令请求的结果是设备给Host返回bit7 == 1信息。

在这里插入图片描述

第二个字节0x06从 table 9-4 可以看到Get_DESCRIPTOR是主机获取从机描述符。

在这里插入图片描述

第三四个字节合起来是0x03 02对照标准的设备请求表可以知道这是就是主机请求获取设备的字符串描述符且为第二个索引。

在这里插入图片描述

在这里插入图片描述

第五六字节合起来是 0x04 09对照标准的设备请求表可以知道这里是指定字符串描述符的语言ID。

第七八字节合起来是 0xFF表示即代表返回的字符串长度不应该多于 255 个字节。

在这里插入图片描述
分析总结该请求为主机获取设备的字符串描述符。


阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6