0%

Linux驱动之USB子系统(一)USB电器特性

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

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

USB设备状态切换图


  • 连接(Attached):USB设备在已连接到USB,但还没有上电的时候处于连接状态
  • 上电(Powered):USB设备在已连接到USB,并且已经上电,但还没有被复位的时候,处于上电状态 USB设备的电源获取分为两种,一种是通过外部电源进行获取,另一种是通过设备所连接的集线器(hub)处获得电源。通过外部供电的USB设备被称为自供电(self-powered)设备。尽管自供电设备在连接到USB之前可能已经有了电源,但在连接到USB并且VBUS被应用到设备之前,它们不被认为是处于上电状态。USB设备可以同时支持自供电和总线供电(bus-powered)的配置。某些设备配置支持任一电源,其他设备配置可能只有在设备是自供电的情况下才可用。设备通过配置描述符(configuration descriptor)报告其电源能力(power source capability)。当前电源作为设备状态的一部分进行报告。
  • 默认(Default):USB设备在已连接到USB,且已经上电,并已经复位,但还没有分配唯一的地址时,处于默认状态,设备响应默认地址
    当复位过程完成后,USB设备以正确的速度运行(即低速low-speed/全速full-speed/高速high-speed)。低速和全速的速度选择由设备端终端电阻决定。作为复位过程的一部分,能够高速运行的设备决定是否以高速运行。
  • 地址(Address):USB设备在已连接到USB,且已经上电和复位,并已分配了一个唯一的设备地址,但还没有被配置时,处于地址状态
    在完成Set Address请求后,如果指定的地址是个非零地址,则设备进入地址状态;否则,设备将保持处于默认状态。
  • 配置(Configured):USB设备已连接到USB,已上电和复位,已分配了一个唯一的设备地址,并且已配置,且未挂起,处于配置状态
    配置设备或改变备用设置,会导致与受影响接口中的端点相关的所有状态和配置值被设置为其默认值。这包括任何使用数据切换(data toggle)的端点将其数据切换(data toggle)重置成值DATA0。
  • 挂起(Suspended):USB设备在已连接到USB,且已上电,并且3ms内未看到总线活动时,USB设备会进入挂起状态

硬件线路

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

USB总线信号

USB连接线有4条:5V、D+、D-、GND。数据线D+、D-,只能表示4种状态。USB协议中,很巧妙地使用这两条线路实现了信号1、信号0、SE0状态、SE1状态、J状态、K状态、空闲IDLE、开始SOP、结束EOP、复位Reset、Suspend信号、Resume信号、SYNC信号、Connect信号、Disconnect信号等。

低速/全速信号电平

高速信号电平

数据信号

  • Reset信号

    • 主机拉低两根信号线(SE0状态)并保持10ms
    • USB设备看到Reset信号后,需要准备接收"SetAddress()"请求;如果它不能回应这个请求,就是"不能识别的设备"
  • Suspend信号

    • 总线3ms以上的IDLE状态,则设备会认为主机发起了一次挂起操作
  • Resume信号

    • Resume信号可以由USB主机发起,也可以由USB设备本身触发,但是只有USB主机可以结束Resume信号
    • 主机在挂起设备后可通过翻转数据线上的极性并保持20ms来唤醒设备,并以低速EOP信号结尾
    • 如果设备支持远程唤醒,设备可向主机发起远程唤醒请求,前提是设备已进入idle状态至少5ms,设备会驱动总线进入K状态,如下图,K状态必须维持1ms-15ms之内,此信号会在1ms内被主机接管,主机会继续驱动唤醒信号直到20ms,并以低速EOP信号结尾
  • SYNC信号

    • 低速设备的SYNC信号,3个KJ状态的切换,后跟随2位时间的K状态,完成一次同步信号的发送Idle-K-J-K-J-K-J-K-K
    • 高速模式中的SYNC格式为:KJKJKJKJ KJKJKJKJ KJKJKJKJ KJKJKJKK,即15对KJ,外加2个K
  • Connect信号
    Hub端口的D+、D-都有15K的下拉电阻,平时为低电平。全速设备内部的D+有1.5K的上拉电阻,低速设备内部的D-有1.5K的上拉电阻,连接到Hub后会导致Hub的D+或D-电平变化,Hub根据变化的引脚分辨接进来的是全速设备还是低速设备。

    高速设备一开始也是作为全速设备被识别的。

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

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

  • Disconnect信号
    对于低速、全速设备,接到Hub时导致D-或D+引脚变为高电平,断开设备后,D-或D+引脚变为低电平:

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

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

    当断开高速设备后,Hub发出信号,得到的反射信号无法衰减,Hub监测到这些信号后就知道高速设备已经断开,内部电路图如下:

  • SOP信号 (Start Of Packet)

    • 低速设备SOP信号:总线从IDLE状态(J状态:差分0)切到K状态(差分1),即可完成低速SOP信号的发送
    • 全速设备SOP信号:总线从IDLE状态(J状态:差分1)切到K状态(差分0),即可完成全速SOP信号的发送
  • EOP 结束包(End of Packet)

    • 全速或低速设备的结束包:SE0状态用于发信号通知分组结束(EOP)。 通过将D +和D-驱动到SE0状态两位时间,然后将线路驱动到J状态一位时间来发信号通知EOP。 从SE0到J状态的转换定义了接收器处的分组的结束。 J状态被置位一个位时间,然后D +和D-输出驱动器都处于高阻态。 总线终端电阻将总线保持在空闲状态
    • 高速设备的EOP:在高速信号中,以从EOP之前的最后一个符号到相反符号的转换开始。这个相反的符号是EOP模式中的第一个符号对于SOF以外的高速数据包。故意生成位填充错误以指示EOP。需要接收器将任何位错误解释为EOP。发送的EOP定界符必须是没有位填充的NRZ字节01111111。例如,如果EOP字段之前的最后一个符号是J,则这将导致EOP为KKKKKKKK。对于高速SOF,传输的EOP分隔符需要5个NRZ字节而不需要填充比特,由01111111 11111111 11111111 11111111 11111111组成。因此,如果EOP字段之前的最后一位是J,这将导致线路上有40个K状态,线路必须返回到高速空闲状态。额外的EOP长度对接收器没有意义,它用于断开检测

NRZI与位填充

参考文章:USB的NRZI信号格式
NRZI:Non Return Zero Inverted Code,反向不归零编码。NRZI的编码方位为:对于数据0,波形翻转;对于数据1,波形不变。

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

NRZI数据格式如上图所示。

使用NRZI时,如果传输的数据总是"1",会导致波形维持不变。如果电平长时间维持不变,比如传输100位1时,如果接收方稍有偏差,就可能认为接收到了99位1、101位1。而USB中采用了Bit-Stuffing位填充处理,即在连续发送6个1后面会插入1个0,强制翻转发送信号,从而让接收方调整频率,同步接收。而接收方在接收时只要接收到连续的6个1后,直接将后面的0删除即可恢复数据的原貌。

设备速率识别

低速/全速

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

高速

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

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

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

  • 对于低速设备,Hub端口不会监测它能否工作于高速模式。低速设备不能兼容高速模式
  • Hub端口发出SE0信号(10ms),这就是复位信号
  • USB设备监测到SE0信号后,会发出"a high-speed detection handshake"信号表示自己能支持高速模式,这可以细分为一下3种情景
    • 如果USB设备原来处于"suspend"状态,它检测到SE0信号后,就发出"a high-speed detection handshake"信号
    • 如果USB设备原来处于"non-suspend"状态,并且处于全速模式,它检测到SE0信号后,就发出"a high-speed detection handshake"信号。这个情景,就是一个设备刚插到Hub端口时的情况,它一开始工作于全速模式
    • 如果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"信号
    • 收到一系列的"Chirp K"、"Chirp J"信号:USB设备端口D+的上拉电阻,使能高速模式
    • 没有收到一系列的"Chirp K"、"Chirp J"信号:USB设备转入全速模式

参考文献

https://blog.csdn.net/weiaipan1314/article/details/113639911
《韦东山老师相关课程》
《USB2.0协议规范》