工业互联网(二)——USB 设备编程(一)

前言:

USB 本身是一个很庞大、复杂的体系,本课程的重点在于工业互联,USB 是其中的一个小小知识点。本章课程的目的 在于:能理解 USB 的一些概念,能使用 USB 传输数据,本节主要介绍 USB 概念,最后移植 USBX 实现 USB 串口功能。

在学习之前,先记住几个术语,这在后面的代码会经常看到

① HCD(Host Controller Driver)主机控制器驱动程序

② DCD(Device Controller Driver)设备控制器驱动程序

③ PCD(Low layer USB Peripheral Control Driver)底层USB外设控制驱动程序

④ CDC(Communication Device Class)通信设备类

USB 系统硬件框架和软件框架:

1.实验现象

现象:把 USB 设备比如 Android 手机接到 PC

① 右下角弹出"发现 android phone"

② 跳出一个对话框,提示你安装驱动程序

问 1:USB 设备插到电脑上去,接触到的对方设备是什么?

答 1:是 USB 控制器,是 USB 控制器内嵌的 root hub

问 2. 既然还没有"驱动程序",为何能知道是"android phone"?

答 2. windows 里已经有了 USB 的总线驱动程序,接入 USB 设备后,是"总线驱动程序"知道你是"android phone"、提示你安装的是"设备驱动程序"。USB 总线驱动程序负责:识别 USB 设备, 给 USB 设备找到对应的驱动程序。

问 3. 为什么一接入 USB 设备,PC 机就能发现它?

答 3. PC 的 USB 口内部,D- 和 D+ 接有 15K 的下拉电阻,未接 USB 设备时为低电平 。USB设备的 USB 口内部,D- 或 D+ 接有 1.5K 的上拉电阻;它一接入 PC,就会把 PC USB 口的 D- 或D+ 拉高 ,从硬件的角度通知 PC 有新设备接入。(不过这只限于低速和全速 类型的USB端口和USB设备,后面会介绍识别高速类型的方法)

问 4. USB 设备种类非常多,为什么一接入电脑,就能识别出来它的种类?

答 4. PC 和 USB 设备都得遵守一些规范。比如:USB 设备接入电脑后,PC 机会发出"你是什么"?USB 设备就必须回答"我是 xxx", 并且回答的格式是固定的。USB 总线驱动程序会发出某些命令想获取设备信息(描述符),USB 设备必须返回"描述符"给 PC。

问 5. PC 机上接有非常多的 USB 设备,怎么分辨它们?

答 5. 每一个 USB 设备接入 PC 时,USB 总线驱动程序都会给它分配一个编号。PC 机想访问某个 USB 设备时,发出的命令都含有对应的编号(地址)。

问 6. USB 设备刚接入 PC 时,还没有编号;那么 PC 怎么把"分配的编号"告诉它?

答 6. 新接入的 USB 设备的默认编号是 0,在未分配新编号前,PC 使用 0 编号和它通信。(也就是说,如果同时有多个 USB 设备接入PC,那么PC只能先给一个设备编号,因为默认只能使用编号0

2.硬件框架

在 USB 系统中,有 2 个硬件概念

① USB Host(USB控制器 ):它跟处理器相连,处理器通过 USB Host 跟各类 USB 设备通信。USB Host 中集成有一个 root hub

② USB Device:这分为两类设备

a. Hub:用来扩展 USB 接口

b. Function:就是普通的 USB 设备,比如 U 盘、声卡等

从这个图可以知道,CPU通过USB控制器连接Hub(USB扩展口 )或Func(USB设备),而且最多只能有6级Hub,第7级必定为USB设备

3.软件框架

APP可以通过USB设备驱动程序访问USB设备,也可以绕过USB设备驱动,直接通过USB控制器驱动访问USB设备。

软件工程师眼里的 USB 电气信号

1.USB 设备状态切换图

USB 2.0 协议支持 3 种速率:低速(Low Speed,1.5Mbps)、全速(Full Speed, 12Mbps)、高速(High Speed, 480Mbps)。

USB Hub、USB 设备,也分为低速、全速、高速 三种类型。一个 USB 设备,可能兼容低速、全速,可能兼容全速、高速,但是不会同时兼容低速、高速。

2.硬件线路

下图是兼容高速模式的 USB 收发器电路图:

USB 连接涉及 Hub Port 和 USB 设备,硬件连接如下:

可以看到在Hub端口没有上拉电阻,在USB设备没有下拉电阻,怎么理解这个图呢?往下看:

Hub 端口引出四根线,其中 D- 和 D+ 是一对差分信号线 。当 Hub 端口未连接 USB 设备时,D- 和 D+ 通过 15kΩ 下拉电阻接地,保持低电平;而 USB 设备端的 D- 或 D+ 则通过 1.5kΩ 上拉电阻接高电平。一旦 USB 设备接入 Hub 端口,设备端的上拉电阻就会将 Hub 端对应的 D- 或 D+ 从低电平拉高为高电平。正是通过这两根线的电平组合,系统可以区分出 4 种状态(00、01、10、11) ,从而识别设备的接入与类型

3.电子信号

USB 连接线有 4 条:5V、D+、D-、GND。数据线 D+、D-,只能表示 4 种状态。USB 协议中,很巧妙地使用这两条线路**实现了空闲(Idle)、始(SOP)、传输数据(Data)、结束(EOP)**等功能。

4.低速/全速信号电平

注意:看上图虚线部分,对于不同速率的设备,J状态和K状态的差分信号不同。J/K状态只是差分信号的别名而已。

5.高速信号电平

6.设备连接与断开

(1)连接

Hub端口的D+、D-都有15K的下拉电阻,平时为低电平。全速设备内部的D+有1.5K的上拉电阻,低速设备内部的D-有1.5K的上拉电阻 ,连接到Hub后会导致Hub的D+或D-电平变化,Hub根据变化的引脚分辨接进来的是全速设备还是低速设备高速设备一开始也是作为全速设备被识别的 。全速设备、高速设备连接时,D+引脚的电平由低变高:

可以看到全速设备、高速设备连接时,D+引脚的电平由低变高:

低速设备连接时,D-引脚的电平由低变高:

(2)断开

对于低速、全速设备,接到Hub时导致D-或D+引脚变为高电平,那断开设备后,D-或D+引脚自然会变为低电平:

对于高速设备 ,它先作为全速设备被识别出来,然后再被识别为高速设备。工作于高速模式时,D+的上拉电阻是断开的 ,所以对于工作于高速模式的USB设备,无法通过D+的引脚电平变化监测到它已经断开。

但工作于高速模式的设备,D+、D-两边有45欧姆的下拉电阻 ,用来消除反射信号

原理:当 Hub 与高速设备连接时,Hub 向高速设备发出信号,由于高速设备端接有 45Ω 下拉电阻,该电阻会吸收(消除)反射信号,因此反射回来的信号幅度基本不变 ;而当高速设备断开后,Hub 再发出信号时,反射信号无法被衰减,发出的信号与反射回来的信号发生叠加,导致信号幅度显著增大Hub 正是通过监测到这种异常增大的信号幅度,来判断高速设备已经断开 。内部电路图如下:

7.复位

从状态切换图上看,一个 USB 设备连接后,它将会被供电,然后被复位。当软件出错时,我们也可以发出复位信号重新驱动设备。

那么,USB Hub 端口或 USB 控制器端口如何发出复位信号?发出 SE0 信号,并维持至少10ms

USB 设备看到 Reset 信号后,需要准备接收"SetAddress()"请求;如果它不能回应这个请求,就是"不能识别的设备"。

8.设备速率识别

(1)低速/全速

复制代码
    Hub 端口的 D+、D-都有 15K 的下拉电阻,平时为低电平。**全速设备内部的 D+有 1.5K 的上拉电阻,低速设备内部的 D-有 1.5K 的上拉电阻,连接到 Hub 后会导致 Hub 的 D+或 D-电平变化,Hub 根据变化的引脚分辨接进来的是全速设备还是低速设备**。
    ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/d33a94708c4c4a54b31fcd5dca5fe080.png)

(2)高速

高速设备必定兼容全速模式,所以高速设备内部 D+也有 1.5K 的上拉电阻,只不过这个电阻是可以断开的:工作于高速模式时要断开它。

高速设备首先作为全速设备被识别出来,然后 Hub 如何确定它是否支持高速模式?

Hub 端口如何监测一个新插入的 USB 设备能否工作于高速模式?流程如下:

① 对于低速设备,Hub 端口不会监测它能否工作于高速模式。低速设备不能兼容高速模式。(D-)

② Hub 端口发出 SE0 信号,这就是复位信号SE0就是D-和D+都是低电平

③ USB 设备监测到 SE0 信号后,会发出"a high-speed detection handshake"信号表示自己能支持高速模式,这可以细分为一下 3 种情景:

a. 如果 USB 设备原来处于"suspend"状态,它检测到 SE0 信号后,就发出"a high-speed detection handshake"信号。

b. 如果 USB 设备原来处于"non-suspend"状态,并且处于全速模式,它检测到 SE0 信号后,就发出"a high-speed detection handshake"信号。这个情景,就是一个设备刚插到 Hub 端口时的情况,它一开始工作于全速模式。

c. 如果 USB 设备原来处于"non-suspend"状态,并且处于高速模式,它会切换回到全速模式(重新连接 D+的上拉电阻),然后发出"a high-speed detection handshake"信号。

"a high-speed detection handshake"信号,就是"高速设备监测握手信号",既然是握手信号,自然是有来有回:

① USB 设备维持 D+的上拉电阻,发出"Chirp K "信号,表示自己能支持高速模式

② 如果 Hub 没监测到"Chirp K "信号,它就知道这个设备不支持高速模式

③ 如果 Hub 监测到"Chirp K "信号后,如果 Hub 能支持高速模式,就发出一系列的 "Chirp K " 、 "Chirp J"信号,这是用来通知 USB 设备:Hub 也能支持高速模式。发出一系列的"Chirp K "、 "Chirp J"信号后,Hub 继续维持 SE0 信号直到 10ms。

④ USB 设备发出"Chirp K "信号后,就等待 Hub 回应一系列的"Chirp K"、"Chirp J"信号

a.收到一系列的"Chirp K"、"Chirp J"信号:USB 设备端口 D+就会断开的1.5kv上拉电阻 ,使能高速模式

b. 没有收到一系列的"Chirp K"、"Chirp J"信号:USB 设备转入全速模式

第一个红虚框是Hub发出SE0复位信号

9.数据信号

(1).低速/全速的SOP和EOP

SOP:Start Of Packet,Hub驱动D+、D-这两条线路从Idle状态变为K状态。SOP中的K状态就是SYNC信号(同步信号)的第1位数据,SYNC格式为3对KJ外加2个K。

怎么理解呢?从前面的低速/全速信号电平图来看

以全速设备为例:全速设备平时处于 Idle/J 状态(D+ 为高电平、D- 为低电平)。当它开始发一个数据包时,D+ 由高电平变为低电平、D- 由低电平变为高电平,即进入 K 状态。SOP 正是 D+、D- 高低电平发生转变的瞬间。(注意:这个Idle/J 状态,对于全速设备和低速设备是不一样的)

从前面的图我们可以知道发送一个数据包,你要先发送SOP,然后发送SYNC(同步信号),那什么是同步信号呢?

在了解同步信号前,我们回顾一下之前学习的UART,它是如何靠一根数据线实现数据传输的?答:双方约定好同一个波特率

通过双方约定好的发送速率,A 会向 B 发送一个持续 1T 时间段的电平信号作为起始信号;B 在收到起始信号后,从起始信号开始计时,等到 1.5T 时刻就可以读取这个信号。

那对于 I2C 和 SPI 呢?它们都有两根线:一根是时钟线(SCK/SCL),一根是数据线(SDA/MOSI、MISO)。时钟线由主机产生固定频率的时钟信号,数据在时钟的边沿(上升沿或下降沿)被采样 。以 I2C 为例,发送方 A 在时钟低电平期间改变数据线上的电平,接收方 B 则在时钟高电平期间读取数据线上的电平,从而保证数据在采样时刻是稳定的。(I2C 这种就是同步通信:发送方和接收方共用一根时钟线(SCL),由主机统一产生时钟信号,双方在时钟的边沿上对齐采样时刻,因此不需要像 UART 那样靠约定波特率来同步.

对于USB系统,它只有一根数据线,那能不能只靠一根数据线也能实现同步信号呢?可以的,怎么实现的?

以AB为例,A在向B发送数据前,会先B发送同步信号(即A的固定频率),B接收到这段同步信号,就知道A的一个周期时间T是多少

EOP:End Of Packet,由数据的发送方发出EOP,数据发送方驱动D+、D-这两条线路,先设为SE0状态并维持2位时间,再设置为J状态并维持1位时间,最后D+、D-变为高阻状态,这时由线路的上下拉电阻使得总线进入Idle状态。

(2) 高速的SOP

高速的EOP比较复杂,作为软件开发人员无需掌握。

高速模式中,Ide状态为:D+、D-接地。SOP格式为:从Idle状态切换为K状态。SOP中的K状态就是

SYNC信号的第1位数据。

高速模式中的SYNC格式为:KJKJKJKJ KJKJKJKJ KJKJKJKJ KJKJKJKK,即15对KJ,外加2个K。

(3). NRZI与位填充

NRZI:Non Return Zero Inverted Code,反向不归零编码。NRZI的编码方位为:对于数据0,波形翻转;对于数据1,波形不变。

使用NRZI,发送端可以很巧妙地把"时钟频率"告诉接收端:只要传输连续的数据0即可。在下图中,低速/全速协议中"Sync Pattern"的原始数据是"00000001",接收端从前面的7个0波形就可以算出"时钟频率"

使用NRZI时,如果传输的数据总是"1",会导致波形维持不变。如果电平长时间维持不变,比如传输100位1时,如果接收方稍有偏差,就可能认为接收到了99位1、101位1。

而USB中采用了Bit-Stuffing位填充处理,即在连续发送6个1后面会插入1个0,强制翻转发送信号,从而让接收方调整频率,同步接收。而接收方在接收时只要接收到连续的6个1后,直接将后面的0删除即可恢复数据的原貌。

NRZI数据格式如上图所示。

USB 协议层数据格式

1.硬件拓扑结构

compound device :多个设备组合起来,通过 HUB 跟 Host 相连(即Host是一主多从,可以和多个设备连接

composite device :一个物理设备有多个逻辑设备(multiple interfaces)

物理设备:指的是实际连接到计算机或其他主机设备上的USB硬件设备,比如USB闪存驱动器、打印机、键盘、鼠标等。

逻辑设备:是指在一个物理USB设备内部,可以独立运行和管理的多个功能模块或接口。每个逻辑设备可以执行不同的功能,并在系统中表现为独立的设备。

例如:一个USB打印机可能内部有多个逻辑设备:

**打印功能:**作为打印机的主要功能。

**扫描功能:**如果打印机是多功能设备,还可能包括扫描功能。

**传真功能:**如果打印机还具备传真功能。

在软件开发过程中,我们可以忽略 Hub 的存在,硬件拓扑图简化如下:

一个物理设备里面可能有多个逻辑设备,Host可以外接多个逻辑设备,硬件拓扑图如下:

2.协议层

要理解协议层、理解数据如何传输,带着这几个问题:

① 如何寻址设备?

② 如何表示数据方向(读、还是写)

③ 如何确认结果?

提前罗列出答案:

① USB 系统是一个 Host 对应多个设备,要传输数据首先要通知设备:

发出 IN 令牌包:表示想读数据,里面含有设备地址
发出 OUT 令牌包:表示想写数据,里面含有设备地址

② 数据阶段:

Host 想读数据:前面发出 IN 令牌包后,现在读取数据包
Host 想发出数据:前面发出 OUT 令牌包后,现在发出数据包

③ 结果如何?有握手包

Host 想读数据,设备可能未就绪,就会回应 NAK 包
Host 想写数据,它发出数据后,设备正确接收了,就回复 ACK 包

(2.1) 字节/位传输顺序

先传输最低位(LSB)。在后续文档中,描述数据时按照传输顺序从左到右列出来。

(2.2) SYNC域

Host发出SOP信号后,就会发出SYNC信号:它是一系列的、最大传输频率的脉冲,接收方使用它来同步数据 。对于低速/全速设备,SYNC信号是8位数据(从左到右是00000001);

对于高速设备,SYNC信号是32位数据(从左到右是00000000000000000000000000000001)。使用NRZI编码时,前面每个"0"都对应一个跳变。

在很多文档里,把SOP和SYNC统一称为"SYNC",它的意思是"SYNC"中含有"SOP"。

3.包格式

USB 总线上传输的数据以包为单位。USB 包里含有哪些内容("域":SOP、SYNC等都是一个域)?

① SOP:用来表示包的起始

② SYNC:用来同步时钟

③ PID:表示包的类型(原来确定数据发送的方向或类型

④ 地址:在 USB 硬件体系中,一个 Host 对应多个 Logical Device,那么 Host 发出的包,如何确定发给谁?

a. 发给所有设备:包里不含有设备地址

b. 发给某个设备:包里含有设备地址、端点号

⑤ 帧号、数据等跟 PID 相关的内容

⑥ CRC 校验码

复制代码
    发起一次完整的传输,可能涉及多个包。那么,第 1 个包里含有设备地址、端点号,后续的包就没必要包含设备地址、端点号

(3.1) PID域

注意:所有的 USB 文档提到的"输入"、"输出",都是基于 Host 的角度,"输出"表示从Host 输出到设备,"输入"表示 Host 从设备得到数据。而且无论是Host向设备输出数据,还是Host从设备得到数据,都是由Host主动向设备发起的

有哪些 USB 包?

根据包数据里的 PID 的 bit1, bit0 可以分为 4 类:

① 令牌包(Token):01B(表示二进制)

② 数据包(Data):11B

③ 握手包(Handshake):10B

④ 特殊包(Special):00B

PID 有 4 位,使用 bit1,bit0 确定分类,使用 bit3,bit2 进一步细分。

在USB包中,PID域使用8位来表示,格式如下:

前4位表示PID,后4位是对应位的取反。接收方发现后4位不是前4位的取反的话,就认为发生了错误。

(3.2) 令牌包(Token)

令牌类的PID,起"通知作用",通知谁?SOF令牌包被用来通知所有设备,OUT/IN/SETUP令牌包被用来通知某个设备

对于OUT(0011)、IN(1001)、SETUP(1101)令牌包 ,它们都是要通知到具体的设备,格式如下:

对于 SOF 包,英文名为"Start-of-Frame marker and frame number"。对于 USB 全速设备,Host 每 1ms 产生一个帧;对于高速设备,每 125us 产生一个微帧,1 帧里有 8 个微帧。Host 会对当前帧号进行累加计数,在每帧或每微帧开始时,通过 SOF 令牌包发送帧号。对于高速设备,每 1 毫秒里有 8 个微帧,这 8 个微帧的帧号是一样的,每 125us 发送一个SOF 令牌包。

SOF 令牌包格式如下:

(3.3) 数据包

Host使用OUT、IN、SETUP来通知设备:我要传输数据了。数据通过"数据包"进行传输。

数据包也有4种类型:DATA0、DATA1、DATA2、MDATA。其中DATA2、MDATA在高速设备中使用。对

软件开发人员来说,我们暂时仅需了解DATA0、DATA1。

为什么要引入DATA0、DATA1这些不同类型的数据包?为了纠错。

Host和设备都会维护自己的数据包切换机制,当数据包成功发送或者接收时,数据包类型切换。当检测

到对方使用的数据包类型不对时,USB系统认为发生了错误。

比如:

1、Host发送DATA0给设备,设备返回ACK表示成功接收,设备期待下一个数据是DATA1

2、但是Host没有接收到ACK,Host认为数据没有发送成功,Host继续使用DATA0发送上一次的数据

3、设备再次接收到DATA0数据包,它就知道:哦,这是重传的数据包

数据包格式如下:

注意:这里的 PID 不再是令牌类型,而是数据类型(DATA0、DATA1、DATA2、MDATA)。

(3.4 )握手包

握手包有4类:ACK(确认)、NAK(无应答)、STALL(挂起)、NYET(未准备好)

① ACK:数据接收方用来回复发送方,表示正确接收到了数据并且有足够的空间保存数据。

② NAK:Host 发送数据给设备时,设备可以回应 NAK 表示"我还没准备好,没办法接收数据"; Host 想读取设备的数据时,设备可以回复 NAK 表示"我没有数据给你"。

③ STALL:表示发生了错误,比如设备无法执行这个请求(不支持该断点等待)、端点已经挂起。设备返回 STALL 后,需要主机进行干预才能接触 STALL 状态。

④ NYET:仅适用于高速设备 。Host 可以发出 PING 包用来确认设备有数据,设备可以回应NYET表示"还没呢"。Hub 也可以回应 NYET 表示低速/全速传输还没完结。

4.传输细节

(4.1) 传输(Transfer)和事务(Transaction)

USB传输的基本单位是包(Packet),包的类型由PID表示。一个单纯的包,是无法传输完整的数据。

为什么?比如想输出数据,可以发出OUT令牌包,OUT令牌包可以指定目的地。但是数据如何传输呢?

还需要发出DATA0或DATA1数据包。设备收到数据后,还要回复一个ACK握手包。

所以,完整的数据传输,需要涉及多个包:令牌包、数据包、握手包。这个完整的数据传输过程,被称为事务(Transaction)。

有些事务需要握手包,有些事务不需要握手包,有些事务可以传输很大的数据,有些事务只能传输小量数据。

有四类事务:

1、批量事务:用来传输大量的数据,数据的正确性有保证,时效没有保证。

2、中断事务:用来传输周期性的、小量的数据,数据的正确性和时效都有保证。

3、实时事务:用来传输实时数据,数据的正确性没有保证,时效有保证。

4、建立事务:跟批量事务类似,只不过令牌包是SETUP令牌包。

有四类传输(Transfer):

1、批量传输:就是使用批量事务实现数据传输,比如U盘。(数据要可靠,不需要实时

2、中断传输:就是使用中断事务实现数据传输,比如鼠标。(数据要可靠,也要实时,注意:这里的中断,并没有中断的效果,而是Host周期地向设备发送数据或者读取数据

3、实时传输:就是使用实时事务实现数据传输,比如摄像头。(数据可以不可靠,但要实时

4、控制传输:由建立事务、批量事务组成,所有的USB设备都必须支持控制传输,用于"识别/枚举"

暂时记住这个关系:

1、Bit组成域(Field)

2、域组成包(Packet)

3、包组成事务(Transaction)

4、事务组成传输(Transfer)

(4.2) 过程(stage)和阶段(phase)

复制代码
    事务由多个包组成,比如 Host 要发送数据给设备,这就会涉及很多个包:

① Host 发出 OUT 令牌包,表示要发数据给哪个设备

② Host 发出 DATA0 数据包

③ 设备收到数据后,回应 ACK 包

这个完整的事务涉及 3 个包(Packet),分为 3 个阶段(Phase):

① 令牌阶段(Token phase):由令牌包实现

② 数据阶段(Data phase):由数据包实现

③ 握手阶段(Handshake phase):由握手包实现

事务由包组成,这些包分别处于 3 个阶段(phase):令牌阶段,数据阶段,握手阶段

对于批量传输、中断传输、实时传输,它们分别由一个事务组成,不再细分为若干个过程。

但是控制传输由多个事务组成 ,这些事务分别处于3个过程:建立过程(stage)、数据过程(stage)、状态
过程(stage)。

总结起来就是:

1、控制传输由多个过程(stage)组成,每个过程由一个事务来实现

2、每个事务由多个阶段(phase)组成,每个阶段有一个包来实现

(4.3) 批量传输

批量传输用批量事务来实现,用于传输大量的数据,数据的正确性有保证,时效没有保证。

批量事务由3个阶段(phase)组成:令牌阶段、数据阶段、握手阶段 。每个阶段都是一个完整的包,含有SOP、SYNC、PID、EOP。

下图中各个矩形框就对应一个完整的包。

示例:

(4.4) 中断传输

中断传输用中断事务来实现,用于传输小量的、周期性的数据,数据的正确性和时效都有保证

中断事务由3个阶段(phase)组成:令牌阶段、数据阶段、握手阶段。每个阶段都是一个完整的包,含有SOP、SYNC、PID、EOP。

下图中各个矩形框就对应一个完整的包。

中断事务跟批量事务非常类似,Host使用它来周期性地读数据、写数据。

以鼠标为例,我们需要及时获得鼠标的数据,不及时的话你会感觉鼠标很迟钝。但是USB 协议中并没有中断功能,它使用"周期性的读、写"来实现及时性 。具体过程如下:

① Host 每隔 n 毫秒发出一个 IN 令牌包

② 鼠标有数据的话,发出 DATA0 或 DATA1 数据包给 Host;鼠标没有数据的话,发出 NAK 给Host。

中断事务的优先级比批量事务更高,它要求实时性,而批量事务不要求实时性。

(4.5) 实时传输

实时传输用实时事务来实现,用于传输实时数据,对数据的正确性没有要求。

实时事务由2个阶段(phase)组成:令牌阶段、数据阶段。每个阶段都是一个完整的包,含有SOP、SYNC、PID、EOP。

实时事务不需要握手阶段,一个示例的场景是:为了传输摄像头的实时数据,偶尔的数据错误是可以忍受的,大不了出现短暂的花屏。如果为了解决花屏而重传数据,那就会导致后续画面被推迟,实时性无法得到保证。

下图中各个矩形框就对应一个完整的包。

实时事务跟中断事务非常类似,Host也会周期性的发起实时事务,主要区别在于:

1、实时事务不要求准确性,没有握手阶段

2、实时事务传输的数据量比较大,中断事务传输的数据量比较小

(4.6) 控制传输

在使用批量传输时,使用IN令牌包或OUT令牌包表示数据传输方向。

控制传输的令牌包永远是SETUP ,怎么分辨是读数据,还是写数据?发出SETUP令牌包后,还要发出DATA0数据包,根据数据的内容来确定后续是读数据,还是写数据。这个过程称为"建立事务"(SETUP Transaction)

但是控制传输由多个事务组成,这些事务分别处于3个过程:建立过程(stage)、数据过程(stage)、状态过程(stage)。

① 建立过程(stage),使用 SETUP 事务:Host 发出 SETUP 令牌包、DATA0 数据包、得到 ACK握手包
② 数据过程(stage),使用批量事务:
a. 对于输出:Host 发出 OUT 令牌包,发出 DATA0、DATA1 数据包、得到 ACK 握手包
b. 对于输入:Host 发出 IN 令牌包,读到 DATA0、DATA1 数据包、发出 ACK 握手包
③ 状态过程(stage),使用批量事务:
a. 对于输出:Host 发出 IN 令牌包,读到 DATA1 数据包,发出 ACK 握手包
b. 对于输入:Host 发出 OUT 令牌包,发出 DATA1 数据包,等待 ACK 握手包

对于建立过程,数据包表示读或者写

对于数据过程:是由一个或多个批量事务组成的。当需要传输的数据量较大时,一个批量事务无法承载全部数据,就需要通过多个批量事务分批次完成传输,每个批量事务都包含令牌阶段、数据阶段和握手阶段

对于状态过程:在控制传输过程中,最后一个事务会改变它的方向,那它怎么表示它的状态呢?

在控制写传输:
如果功能执行完成:设备会向Host发送一个数据长度为0的数据包

如果设备还在处理数据:那么设备会发送一个NAK握手包

在控制读传输中:

Host无论是向设备发送数据还是读取设备的数据,状态最后都是由设备通知Host的,例如:如果Host读数据,读完数据后,还得由设备告诉Host,这个读过程已经结束了

那Host是向设备输出数据,那它怎么得到状态呢?这里有一个取巧的过程

具体来说,控制读传输的状态过程是这样的:

  1. 令牌包:OUT + 设备地址 + 端点号 + CRC5 ------ 由 Host 发出,告诉总线上"我要向 XX 设备的 XX 端点写"
  2. 数据包:DATA1 + 空载荷 + CRC16 ------ 还是由 Host 发出,零长度(注意这里必须要有零长度 DATA1
  3. 握手包:ACK/NAK/STALL ------ 设备回应

这里的巧妙之处在于: 控制读传输的数据过程是 Host 从设备读取数据(方向是设备→Host),但状态过程却反过来了------由 Host 向设备发出 OUT 令牌包,设备则通过回应握手包来告诉 Host 状态过程是否执行完成。如果设备还在处理数据,它会回应 NAK 握手包,Host 就会继续重试,直到设备准备好为止。

上图中的每一个方框,都是一个完整的事务,含有:Token Packet、Data Packet、Handshake Packet。

在上面建立过程 中,我不是说过数据包 表示读或者写,后续我们会了解这个数据包是怎么表示读还是写?

相关推荐
G***技1 小时前
IB3-771嵌入式主板6 TOPS真实算力怎么用:从PyTorch到RKNN的量化落地
人工智能·嵌入式硬件
国科安芯1 小时前
低轨卫星姿轨控系统中抗辐射MCU的选型依据与工程实践
单片机·嵌入式硬件·算法·架构·系统安全·低轨卫星·抗辐射
国科安芯1 小时前
卫星电源管理系统中高可靠MCU的功耗特性与电源监控功能分析
人工智能·单片机·嵌入式硬件·mcu·安全·电源管理系统·抗辐射
qq_402995752 小时前
诊断协议栈配置Agent
arm开发·人工智能·stm32·单片机·mcu
西城微科方案开发2 小时前
制氧机方案——方案开发商西城微科
单片机·嵌入式硬件
国科安芯2 小时前
小卫星综合电子系统中功能安全与抗辐射加固的协同设计研究
嵌入式硬件·安全·架构·risc-v·抗辐射·小卫星·综合电子系统
LCG元3 小时前
STM32L4 STOP2 模式下 LPUART 串口唤醒:三种唤醒方式实测对比与避坑指南
stm32·单片机·嵌入式硬件
意法半导体STM323 小时前
【官方原创】STM32CubeMX2 1.1.0新版本发布
stm32·单片机·嵌入式硬件·mcu
周洲08303 小时前
【无标题】STM32 串口 Printf 重定向|标准库 + HAL库 两套极简通用代码(无需MicroLIB)
stm32·单片机·嵌入式硬件