USB 基础

第一章 USB协议解析


目录

第一章 USB协议解析

前言

一、USB的全称: Universal Serial Bus(通用串行总线)

二、USB的特点:可扩展,即插即用

三、USB协议版本

四、USB的总线拓扑图

4.1 Host:usb主机控制器

4.2 Hub: 集线器

4.3 Func(usb device):usb设备

五、usb总线枚举

5.1 设备描述符

5.2 配置描述符

5.3 接口描述符

5.4 端点描述符

5.5  usb总线枚举流程

问题:为什么要有默认端点0?

六、usb数据传输

6.1 管道(Pipe)

6.2 端点(Endpoints)

6.3 USB协议层

问题:为什么要区分不同的数据传输类型?

参考资料


前言

本文根据usb2.0协议规范,讲解usb基础概念


一、USB的全称: Universal Serial Bus(通用串行总线)

二、USB的特点:可扩展,即插即用

现在的PC机基本都保留了鼠标,键盘,耳机,麦克风的专用接口,但是随着电子产品的发展,PC机的外设接口就不够用了,像打印机,移动硬盘,手机等也需要和PC机交换数据怎么办?为了减少PC机的专用 接口,就需要开发一种通用的数据交换接口,USB就是为了解决这个问题而设计出来的。 

三、USB协议版本

  • usb1.0 – low speed(低速),最大传输速率 1.5Mbps
  • usb 1.1 – full speed(全速),最大传输速率 12Mbps

  • usb 2.0 – high speed(高速),最大传输速率 480Mbps

  • usb 3.0 – super speed(超高速),最大传输速率 5Gbps

四、USB的总线拓扑图

​​​​​​​

来源:USB 2.0 Specification

USB系统由 Host, Hub, Func(usb device) 3部分组成。 

4.1 Host:usb主机控制器

负责usb设备的供电,枚举,配置,数据的发送和接收,usb设备和总线状态的管理等;在嵌入式系统中,host一般都是集成在Soc中;

4.2 Hub: 集线器

提供USB的接入点,即port口,port口接入和拔掉usb设备的状态管理,负责port口的电源管理,向下兼容低速usb设备(如usb1.0的鼠标可以插到usb2.0的接口上使用);一般usb主机控制器也会集成一个hub,叫做root hub(根集线器)

usb物理上的可扩展和即插即用的功能基本就是Hub提供的;

典型的Hub示意图:

​​​​​​​来源:USB 2.0 Specification

4.3 Func(usb device)usb设备

 通过usb接口给主机提供额外功能,如外部存储功能(U盘,移动硬盘),usb鼠标,usb键盘,打印机等。Hub也属于usb设备的一种;

因为在数据传输过程中Hub和usb线都会造成延迟,所以USB总线拓扑图中最多允许有7层的深度(包括Host所在的第一层);

五、usb总线枚举

usb总线枚举很重要的作用就是要知道接入Hub port口的是什么样的usb设备;

比如:只有知道usb设备的最大工作电流,host才能决定是否让usb设备接入;只有知道usb的接口类型,host才能安排合适的软件驱动进行工作等;

usb协议规定使用4种描述符来描述一个usb设备:设备描述符,配置描述符,接口描述符,端点描述符;

4种描述符的层次关系示例如下:

 

5.1 设备描述符

描述usb设备信息,包括厂商ID,产品ID,usb版本号,支持的设备类,子类,设备遵循的协议,默认端点0的最大包长度等;

一个usb设备只有1个设备描述符; 

5.2 配置描述符

描述这个配置包含的接口数量,供电模式,最大工作电流等;

usb设备可以包含1个或多个配置描述符,但工作时只能选1个配置描述符生效;

5.3 接口描述符

描述接口编号,端点数量,接口类,子类和遵循的协议等;一个接口代表一个基本功能,如鼠标功能,键盘功能;

一个usb设备可以有多个接口同时工作;

5.4 端点描述符

描述端点地址,数据传输类型,数据传输方向,数据接收或发送的最大包长度,轮询传输时的轮询频率等;

一个接口可以有多个端点,端点方向分为:输入端点和输出端点,除端点0外,一个端点只能承载一个方向的数据,端点0是默认控制端点,双向数据传输,只要usb设备上电并reset后就可以使用,主要用于设备初始化参数等;

端点的数据传输类型包括:控制,同步,批量,中断;

以上4种描述符的详细定义可参考 USB 2.0 Specification 文档;

5.5  usb总线枚举流程

  1. usb设备插到hub的port口上,hub将会给usb设备供电,并通知host有设备接入;
  2. host至少需要等待100ms,让usb设备完全插入hub的port口并供电稳定,等待完成后,host给hub下发 port enable和 port reset的命令;
  3. hub执行完 port enable和port reset命令后,usb设备的寄存器和状态都被复位,并让默认控制端点0处于工作状态,此时usb设备的工作电流不能超过100mA
  4. host 通过默认控制端点0给usb设备分配和设置一个usb host系统中唯一无歧义的地址
  5. host 从usb设备中读取所有配置信息
  6. host根据每个配置描述的工作电流,优先考虑usb协议标准设备等从中选一个配置,并把这个配置设置到usb设备
  7. host给选中的配置中的所有接口找到合适的驱动

问题:为什么要有默认端点0?

分析:一般来说,端点属于接口,一个接口就表示一个基本功能,但是usb设备刚接到Hub的port口时,host还不知道usb设备支持哪些接口,是usb鼠标还是usb键盘还是其它的usb类型设备,所以不能使用接口中的端点进行数据通信;要确定usb设备支持哪些接口,就需要端口通信来获取各种描述符;所以不管usb设备支持哪些接口,所有类型的usb设备必须要实现端点0的功能;

六、usb数据传输

6.1 管道(Pipe)

usb总线枚举结束后,host给usb设备支持的所有接口功能找到了合适的驱动后,驱动就接管了usb设备的数据传输操作;

数据传输首先要知道的是源地址,目的地址;

源地址就是主机的接收或者发送的缓存物理地址;

目的地址比较复杂,因为usb总线上可以接入多个usb设备,比如主机上可以同时使用usb鼠标,usb键盘,U盘等,所以host必须要给不同的usb设备分配唯一无歧义的设备地址,比如usb鼠标的设备地址是1,usb键盘的设备地址是2,U盘的设备地址是3,这个分配设备地址的操作是在usb总线枚举过程中确定的;

因为每个接口功能还有多个端点,所以数据传输时还需要指定端点,根据端点描述符的定义,端点有地址,方向,传输类型的属性;

所以目的地址就包含:usb设备地址,端点地址,端点方向,端点传输类型;

usb协议中用管道(pipe)来指代目的地址;Linux内核驱动中用一个整形值来表示管道,bit7用来表示端点方向,bit8~bit14表示usb设备地址,bit15~bit18表示端点号,bit30~bit31表示管道类型;

所以,数据传输必须要通过端点,只要提供了管道就能找到对应的端点;

来源:USB 2.0 Specification

6.2 端点(Endpoints)

端点是数据传输的基本单元,端点有地址,方向,类型属性

端点的方向是以host的视角来确定,类型有:IN,OUT

  • IN:host接收usb设备的数据
  • OUT:host发送数据给usb设备

端点的数据传输类型包括:控制,同步,批量,中断

6.2.1 控制传输(Control Transfers)

突发、非周期、主机软件发起的请求/响应数据传输,通常用于命令/状态操作;

比如usb总线枚举过程中获取设备描述符,配置描述符,设置usb设备地址等;

 6.2.2 同步传输(Isochronous Transfers)

周期连续的数据传输,一般是时间敏感的数据流,传输过程不保证数据一定传输正确,但保证在周期内把数据传输完毕;

比如传输的视频流或音频流;

6.2.3 批量传输(Bulk Transfers)

非周期、大数据包突发数据传输,通常用于可以使用任何可用带宽的数据,也可以延迟到可用带宽。

比如U盘文件传输;

6.2.4 中断传输(Interrupt Transfers)

低频、有限延迟的数据传输;

比如usb鼠标和usb键盘的数据传输;  

以上4种传输类型的详细定义请参考 USB 2.0 Specification 文档

6.3 USB协议层

usb协议规定数据流组织方式:bit → packet → transaction → (micro)frame

6.3.1 bit​​​​​​​

usb总线上发送和接受的数据都转化成二进制表示(0和1),再把0和1转换成高低电平; 

6.3.2 packet

多个bit组成一个packet;

packet被划分成多个Field,每个Field由若干个bit组成:SYNC Field, Packet Identifier Field(PID),Address Fields, Frame Number Field,Data Field,CRC Field;

其中Address Fields包括:usb设备地址 和 端点地址;

​​​​​​​

PID:表示packet的类型,常见有3种:token,data,handshake

  • token packet

        由8bit PID + 7bit usb设备地址 + 4bit 端点地址 + 5bit CRC5 组成;        

        PID表示packet的类型:IN,OUT,SETUP

        token packet主要起到确定传输目的地址和方向的作用

  • data packet

        由8bit PID + 0~8192bit data + 16bit CRC16 组成;

        PID表示packet的类型:DATA0,DATA1, DATA2, MDATA

        PID主要用于保证数据传输过程中在多个事务中的数据序列同步

  • handshake packet

        由 8bit PID 组成;

        handshake packet主要用于回复数据传输结果的状态:数据接收成功,命令被接收或被拒绝,处于流控状态,被挂起 等;

详细定义请参考 USB 2.0 Specification 文档

6.3.3  transaction(事务)

由一个或多个packet组成;

一般是 1个 token packet + 1个 data packet + 1 个handshake packet 组成一个事务;根据不同类型的端点,组成transaction的packet个数和类型会有所不同;

抽象理解transaction要干的活:发一个带目的地址和方向(接收或发送)的packet,通知usb总线上对应的usb设备准备接收或发送数据,接收或者发送一个data packet,回复数据接收或发送结果;

6.3.4 (micro)frame

由若干个 transaction 组成;

为了保证数据传输的速度和准确性,对于低速或全速(low/full-speed)usb设备,host每隔 1ms 发送一个 Start-of-Frame(SOF) packet,对内部端点时钟和host时钟进行同步;对于高速(high-speed)usb设备,host 每隔 125us 发送一个 Start-of-Frame(SOF) packet;

1ms被定义为frame,125us被定义为micro-frame;

在frame或micro-frame时间内会传输若干个transaction;

来源:USB 2.0 Specification

问题:为什么要区分不同的数据传输类型?

考虑这样的使用场景:一个usb总线上接入了100个U盘和1个usb键盘,100个U盘都在传送大批量的文件,毫无疑问usb总线上大部分时间都在传输U盘文件数据,极小部分时间传输usb键盘数据,那些还未来得及传输的U盘文件数据就会放入长长的buffer队列等待usb总线传输,如果usb键盘数据也放入长长的buffer队列等待传输,就会导致在usb键盘上敲字母的时候,电脑反应很慢,这是不能接受的;

区分不同的数据传输类型,就可以对不同的传输类型使用不同的传输策略,提高usb总线利用率;

比如一座桥上,划分出人行道和机动车道,走路速度慢,只能用人行道通过;车辆速度快,只能从机动车道通过;人行车道远比机动车道窄,这样就可以大大提高这座桥的利用率;

当软件驱动发起一次数据传输,即 IRP(I/O Request Packet),host会把IRP切割成多个 transaction来完成,比如U盘驱动发起一次写10MB数据到U盘的请求,这个请求(IRP)会被切割成多个transaction来完成;

来源:USB 2.0 Specification

我们知道,usb协议规定总线是按(micro)frame来传输数据,每个(micro)frame时间内可以传输若干个transaction,每个transaction可以属于不同端点类型;

来源:USB 2.0 Specification

为了保证对 Control Transfers,Isochronous Transfers,Bulk Transfers,Interrupt Transfers 4种传输类型得到比较公平的数据传输机会,usb协议规定在(micro)frame时间内,传输每种类型的transaction时间占(micro)frame的比例不能超过特定的值;

比如高速(high-speed)usb设备:

control transfers 最多占用20%的micro-frame时间;

isochronous transfers + interrupt transfers(这2种类型都是周期传输) 最多占用 80% 的micro-frame时间;

bulk transfers 只有在micro-frame还有剩余空闲时间时才能进行数据传输;

micro-frame就像是10节车厢的火车,每125us(usb协议规定的micro-frame时间长度)发一趟车,

第1~2节车厢:

  • 优先装载 control transfers的transaction;
  • 如果没装满,优先考虑装载isochronous transfers或 interrupt transfers 的transaction;
  • 如果还没装满,装载 bulk transfers的transaction

第3~10节车厢:

  • 优先装载isochronous transfers或 interrupt transfers 的transaction;
  • 如果没装满,装载 bulk transfers的transaction;

如果10节车厢没有装满,就装载 bulk transfers的transaction;

Linux内核线程调度单位是时间片,usb总线的调度单位是(micro)frame;

usb总线的调度算法值得参考;

参考资料

  1. USB 2.0 Specification
  2. Linux那些事之我是USB
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值