+ -

USB帧、微帧以及数据传输过程

我们知道USB2.0采用的是NRZI编码格式,USB3.0采用的是8B/10B编码,这些都是处于物理层的概念。
今天我们要介绍的是由基于这些硬件编码格式组成的USB最小协议单元-物理层时间基准概念的帧和微帧。这些帧和微帧的组合用于支撑数据链路层数据的传输。

帧的时间

USB在2.0时代,分为低带设备(1.5Mbps),全速设备(12Mbps)和高速设设备(480Mbps).这些设备使用的是帧的时间间隔是1ms,而对于高速设备,又将每个帧分成了8个微帧,这样每个微帧的时间间隔变成了125us。

帧的发起者-主机

说起USB帧,其实指的是USB其实是一种主机控制数据传输的,设备不能主动上报数据,只有主机控制设备才可以上报数据。所以主机不知道设备什么时候有数据(因为没有中断),所以主机只能被动的查询。

每一个帧(微帧)起始点会先发送一个SOF包(帧起始包),它以广播的形式发送,所有USB全速设备和高速设备都可以接收到SOF包。帧起始包之后可以是输出(OUT)、输入(IN)、建立(SETUP)等令牌包(核心:令牌包一定是主机发送的,后续详解),在令牌包中指定数据包去向或者来源的设备地址和端点(Endpoint),从而保证了只有一个设备对被广播的数据包/令牌包作出响应

usb主机和设备控制器同步后,每个微帧起始点开始传输数据,在一个微帧时间里,usb host轮训各个device.一个微帧传输时间里,可以进行 控制传输中断传输批量传输同步传输

通常微帧起始时间到来时,host 控制器发送中断给 主机系统cpu,usb host驱动中断处理函数处理微帧起始 ,把各种传输配置到host 控制器通道中,之后host开始工作,根据配置好的通道轮训各个device,通道对应的某个device 端点。当某个通道传输完成,host中断cpu,驱动处理完成后,清除通道,接着配置下一个通道。

帧起始包在每帧(或微帧)开始时发送,它以广播的形式发送,所有USB全速设备和高速设备都可以接收到SOF包。USB全速设备每毫秒产生一个帧,而高速设备每125us产生一个微帧。

USB数据传输模式

帧起始包之后可以是输出(OUT)、输入(IN)、建立(SETUP)等令牌包
USB 采用“令牌包”-“数据包”-“握手包”的传输机制,在令牌包中指定数据包去向或者来源的设备地址和端点(Endpoint),从而保证了只有一个设备对被广播的数据包/令牌包作出响应。握手包表示了传输的成功与否。

USB 采用轮询的广播机制传输数据,所有的传输都由主机发起,任何时刻整个 USB 体系内仅允许一个数据包的传输,即不同物理传输线上看到的数据包都是同一被广播的数据包。

传输由OUT、IN和SETUP事务构成,传输有四种类型,中断传输批量传输同步传输控制传输,其中中断传输批量传输的结构一样,同步传输有最简单的结构,而控制传输是最重要的也是最复杂的传输。

1610606841268

USB包

包是USB总线数据传输的最小单位,不能被打断或干扰,否则会引发错误。若干个数据包组成一次事务传输,一次事务传输也不能打断,属于一次事务传输的几个包必须连续,不能跨帧完成。一次传输由一次到多次事务传输构成,可以跨帧完成。

USB主机会对当前帧号进行计数,在每次帧开始时通过SOF包发送帧号。SOF中的帧号是11位的。在4个令牌包中,只有SOF令牌包之后不跟随数据传输,其他的都有数据传输。下图是SOF令牌包的结构。每个令牌包,最后都有一个CRC5的校验,它只校验PID之后的数据,不包括PID本身,因为PID本身已经有4个取反的位进行校验了。

1610606872905

OUT、IN、SETUP令牌包的结构。其中,地址域是要访问的设备的地址,端点域是要访问的端点号。
1610606898605

数据包都具有同样的结构:一个同步域,后面跟整数字节的数据,然后是CRC16校验,最后是包结束符EOP
1610606914657

当USB接口芯片正确接收到数据时,如果有空间保存,则它将数据保存并返回ACK,同时,设置一个标志表示已经正确接收到数据;如果没有空间保存数据,则自动会返回NAK。
收到输入请求时,如果有数据需要发送,则发送数据,并等待接收ACK。只有当数据成功发送出去(即接收到应答信号ACK)之后,它才设置标志,表示数据已发送成功;如果无数据需要发送,则它自动返回ACK。

之所以有不同类型的数据包,是用在当握手包出错时纠错。下面以DATA0包和DATA1包的切换为例进行具体的解释。
主机和设备都会维护自己的一个数据包类型切换机制:当数据包成功发送或者接收时,数据包类型切换。当检测到对方所使用的数据包类型不对时,USB系统认为这发生了一个错误,并试图从错误中恢复。数据包类型不匹配主要发生在握手包被损坏的情形。当一端已经正确接收到数据并返回确认信号时,确认信号却在传输过程中被损坏。这时,另一端就无法知道刚刚发送的数据是否已经成功,这时它只好保持自己的数据包的类型不变。如果对方下一次使用的数据包类型跟自己的不一致,则说明它刚刚已经成功接收到数据包了(因为它已经做了数据包切换,只有正确接收才会如此);如果对方下一次使用的数据包类型跟自己的一致,则说明对方没有切换数据包类型,也就是说,刚刚的数据包没有发送成功,这是上一次的重试操作。

握手包用来表示一个传输是否被对方确认,握手包只有同步域、PID和EOP,是最简单的一种数据包,握手包有ACK、NAK、STALL和NYET。

  • ACK表示正确接收数据,并且有足够空间来容纳数据。主机和设备都可以用ACK来确认,而NAK、STALL、NYET只有设备能够返回,主机不能使用这些握手包。
  • NAK表示没有数据需要返回,或者数据正确接收但是没有足够的空间来容纳它们。当主机收到NAK时,知道设备还未准备好,主机会在以后合适的时机进行重试传输。
  • STALL表示设备无法执行这个请求,或者端点已经被挂起了,它表示一种错误的状态,设备返回STALL后,需要主机进行干预才能解除这种STALL状态。
  • NYET只在USB2.0的高速设备输出事务中使用,它表示设备本次数据成功接收,但是没有足够的空间来接收下一次数据。主机在下一次输出数据时,将先使用PING令牌包来试探设备是否有空间接收数据,以避免不必要的带宽浪费。

需要注意的是,返回NAK并不表示数据出错,只是说明设备暂时没有数据传输或者暂时没有能力接收数据。当USB主机或者设备检测到数据出错时,将什么都不返回。这时等待接收握手包的一方就会收不到握手包从而等待超时。

1610606971451

特殊包

特殊包是一些在特殊场合使用的包。总共有4种:PRE、ERR、SPLIT和PING。其中PRE、SPLIT和PING是令牌包,ERR是握手包。

  • PRE是通知集线器打开其低速端口的一种前导包。PRE只使用在全速模式中。平时,为了防止全速信号使低速准备误动作,集线器是没有将全速信号传递给低速设备的。只有当收到PRE令牌包时,才打开其低速端口。PRE令牌包与握手包的结构一样,只有同步域、PID和EOP。当需要传送低速事务时,主机首先发送一个PRE令牌包(以全速模式发送)。对于全速设备,将会忽略这个令牌包。集线器在收到这个令牌包后,打开其连接了低速设备的端口。接着,主机就会以低速模式给低速设备发送令牌包、数据包等。
  • PING令牌包与OUT令牌包具有一样的结构,但是PING令牌包后并不发送数据,而是等待设备返回ACK或者NAK,以判断设备是否能够传送数据。只有在USB2.0高速环境中才会使用PING令牌包,它只被使用在批量传输和控制传输的输出事务中。直接使用OUT令牌包发送数据时,不管设备是否有空间接收数据,都会在OUT令牌包之后跟着发送一个数据包,如果设备没有空间接收数据,就返回一个NAK。这样的结果就是浪费了总线带宽,白白传送了数据。在高速设备中增加了这个PING机制,主机先用PING令牌包试试设备是否有空间接收数据,而不用事先把数据发送出去。
  • SPLIT令牌包是高速事务分裂令牌包,通知集线器将高速数据包转化为全速或者低速数据包发送给其下面的端口。
  • ERR握手包是在分裂事务中表示错误使用。

1610606997682

全速USB传输(帧)

全速USB传输每一个帧为1ms。首先我们看上一帧,首先会发送一个SOF包(帧起始包),此时USB主机检测到总线没有事务可以传输,则总线进入idel(空闲状态),这里的空闲时间996.917us,我们其实可以计算发送一个SOF包的总线有效带宽时间(1000us-996.917us),大概3us左右,大家可能会问,为什么是3us,那就给大家详细计算下。

为什么是3us,因为全速USB 12Mhz的时钟频率,SOF包长度为4字节(同步 1字节+SOF 1字节+Frame域和CRC域 2字节),4*8 = 32bit,传输时间 = 1/12M*32 + 250[EOP] = 83.3333ns*32+250ns = 2916ns = 3us,EOP是end of packet占用的时间,过瘾吧,提示大家下,包后面会详细讲解。

紧接着我们看下一帧,同样的首先会发送一个SOF包(帧起始包),等了176.817us后,可能有事务了,紧接着USB主机会发送一个SETUP令牌包,也就是请求哪个设备哪个端点进行传输,紧接着两个事务传输完成。我们这里一定要注意,第二个事务传输完毕之后,主机检测到没有事务了,总线同样会进入空闲状态,这里空闲了478.767us,大家自行计算。

帧而复始,一直会这样一帧帧下去,主机就是用这种方式和各个设备数据传输的。

usb-full-speed-frame

高速USB传输(微帧)

高速USB传输每一个微帧为125us,含义其实和上面的一样。首先我们看上一帧,首先会发送一个SOF包(帧起始包),此时USB主机检测到总线没有事务可以传输,则总线进入idel(空闲状态),这里的空闲时间124.804us,我们其实可以计算高速传输协议下发送一个SOF包的总线有效带宽时间(125us - 124.804us),大概0.2us左右,大家可能会问,为什么是0.2us,我只想告诉大家,高速USB传输的时钟为480Mhz,如果看到这里还不知道请百度下。

紧接着我们看下一帧,同样的首先会发送一个SOF包(帧起始包),等了17.4us后,可能有事务了,紧接着USB主机会发送一个SETUP令牌包,也就是请求哪个设备哪个端点进行传输,紧接着两个事务传输完成。我们这里一定要注意,第二个事务传输完毕之后,主机检测到没有事务了,总线同样会进入空闲状态,这里空闲了98.704us,大家自行计算。

微帧而复始,一直会这样一帧帧下去,主机就是用这种方式和各个设备数据传输的。
usb-high-speed-frame

  • USB基础
  • USB摄像头UVC
  • USB人机交互HID
  • USB音频UAC
  • Windows基础
  • 磁盘与文件系统
  • Windows编程
  • Windows驱动
  • 开发模块
  • Windows运维
  • Linux相关
  • C语言学习
  • 高级语言
  • 前端开发
  • 服务器开发
  • 数据库
  • 字节流笔记
  • 字节流
  • 微信公众号
    字节流公众号  字节流QQ群:952873936
    取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

    打开支付宝扫一扫,即可进行扫码打赏哦

    Powered by bytekits.com,汇天下文字,成非凡梦想!!!