当前位置:网站首页 > 技术博客 > 正文

usb协议分析仪 力科



USB 全称为 Universal Serial Bus,翻译过来就是通用串行总线。由英特尔与众多电脑公司提出来,用于规范电脑与外部设备的连接与通讯。目前 USB 接口已经得到了大范围的应用,已 经是电脑、手机等终端设备的必配接口,甚至取代了大量的其他接口。

比如最新的智能手机均 采用 USB Typec 取代了传统的 3.5mm 耳机接口,苹果最新的 MacBook 只有 USB Typec 接口, 至于其他的 HDMI、网口等均可以通过 USB Typec 扩展坞来扩展。

按照大版本划分,USB 目前可以划分为 USB1.0、USB2.0、USB3.0 以及即将到来的 USB4.0。

USB1.0:USB 规范于 1995 年第一次发布,由 Inter、IBM、Microsoft 等公司组成的 USBIF(USB Implement Forum)组织提出。USB-IF 于 1996 年正式发布 USB1.0,理论速度为 1.5Mbps。 1998 年 USBIF 在 USB1.0 的基础上提出了 USB1.1 规范。

USB2.0:USB2.0 依旧由 Inter、IBM、Microsoft 等公司提出并发布,USB2.0 分为两个版 本:Full-Speed 和 High-Speed,也就是全速(FS)和高速(HS)。USB2.0 FS 的速度为 12Mbps,USB2.0 HS 速度为 480Mbps。目前大多数单片机以及低端 Cortex-A 芯片配置的都是 USB2.0 接口,比 如 STM32 和 ALPHA 开发板所使用的 I.MX6ULL。USB2.0 全面兼容 USB1.0 标准。

USB3.0:USB3.0 同样有 Inter 等公司发起的,USB3.0 最大理论传输速度为 5.0Gbps,USB3.0 引入了全双工数据传输,USB2.0 的 480Mbps 为半双工。USB3.0 中两根线用于发送数据,另外 两根用于接收数据。在 USB3.0 的基础上又提出了 USB3.1、USB3.2 等规范,USB3.1 理论传输 速度提升到了 10Gbps,USB3.2 理论传输速度为 20Gbps。为了规范 USB3.0 标准的命名,USBIF 公布了最新的 USB 命名规范,原来的 USB3.0 和 USB3.1 命名将不会采用,所有的 3.0 版本 的 USB 都命名为 USB3.2,以前的 USB3.0、USB3.1 和 USB3.2 分别叫做 USB3.2 Gen1、USB3.2 Gen2、USB3.2 Gen 2X2。

USB4.0:目前还在标准定制中,目前还没有设备搭载,据说是在 Inter 的雷电接口上改进而 来。USB4.0 的速度将提升到了 40Gbps,最高支持 100W 的供电能力,只需要一根线就可以完 成数据传输与供电,极大的简化了设备之间的链接线数,期待 USB4.0 设备上市。

最常见的就是 USB A 插头和插座如下:

image

USB-A有4根线,第 1 根线为 VBUS,电压为 5V,第 2 根线为 D-,第 3 根线为 D+,第 4 根线为 GND。USB 采用差分信号来传输数据,D-和 D+两根差分信号线。第1根和第4根用来供电,因此仔细去看会发现触点稍长与第2第3个触点。

image

image

使用过JLINK 调试器的朋友应该还见过USB B插头和插座。

image

image

Mini USB 有 5 个触点,也就是 5 根线。第 1 根线为 VCC(5V),第 2 根线为 D-,第 3 根线为 D+,第 4 根线为 ID, 第 5 根线为 GND。可以看出 Mini USB 插头相比 USB A 插头多了一个 ID 线,这个 ID 线用于 实现 OTG(后面有讲) 功能,通过 ID 线来判断当前连接的是主设备(HOST)还是从设备(SLAVE)

image

以前的安卓手机,包括现在还有很多蓝牙耳机,数据线充电线都还是Micro USB的。不过已经慢慢被USB TypeC取代了。

现在最流行的就是 USB TypeC了,笔记本电脑,手机,耳机,数据线充电线都慢慢喜欢用TypeC了。

image

USB 是一种支持热插拔的总线接口,使用差分线(D-和 D+)来传输数据,USB 支持两种供 电模式:总线供电和自供电,总线供电就是由 USB 接口为外部设备供电,在 USB2.0 下,总线 供电最大可以提供 500mA 的电流。

1.0使用低速模式,1.1开始支持全速模式,2.0开始支持高速模式,3.0开始支持超速模式。

OHCI:全称为 Open Host Controller Interface,这是一种 USB 控制器标准,厂商在设计 USB 控制器的时候需要遵循此标准,用于 USB1.1 标准。OHCI 不仅仅用于 USB,也支持一些其他的 接口,比如苹果的 Firewire 等,OHCI 由于硬件比较难,所以软件要求就降低了,软件相对来说 比较简单。OHCI 主要用于非 X86 的 USB,比如扩展卡、嵌入式 USB 控制器。

UHCI:全称是 Universal Host Controller Interface,UHCI 是 Inter 主导的一个用于 USB1.0/1.1 的标准,与 OHCI 不兼容。与 OHCI 相比 UHCI 硬件要求低,但是软件要求相应就高了,因此 硬件成本上就比较低。

EHCI:全称是 Enhanced Host Controller Interface,是 Inter 主导的一个用于 USB2.0 的 USB 控制器标准。EHCI 仅提供 USB2.0 的高速功能,至于全速和低速功能就由 OHCI 或 UHCI 来提供。市面上大部分usb host都支持EHCI。

xHCI:全称是 eXtensible Host Controller Interface,是目前最流行的 USB3.0 控制器标准, 在速度、能效和虚拟化等方面比前三个都有较大的提高。xHCI 支持所有速度种类的 USB 设备, xHCI 出现的目的就是为了替换前面三个。

USB也是分为主机和从机两部分,一般主机叫做 Host,从机叫做 Device,比如我们的电脑USB是主机,接的USB外设如键盘,鼠标,u盘等被叫做从机。

我们电脑带的USB A 插座数量就决定了你能外接多少个USB设备,如果不够用的话我们可以购买 USB集线器来扩展电脑的 USB 插口,USB 集线器也叫做 USB HUB, 下图是一个一拖四的 USB HUB,也就是将一个 USB接口扩展为 4 个。

image

虽然我们可以对原生的USB口数量进行扩展,但是不能对拓展口的带宽速率进行扩展,比如我有一个USB host 带宽最大为 480Mbps,对它进行usb hub拓展成4个口,这样四个口的带宽总速率就是480Mbps。

以nxp主控为例,使用 GL850G 这个 HUB 芯片将 I.MX6ULL 的 USB OTG2 扩展成了 4 路 HOST 接口。

image

其中 HUB_DP4/DM4 用于 4G 模块,因 此对外提供的只有三个 USB HOST 接口,这三个 USB HOST 接口如下:

image

USB 只能主机与设备之间进行数据通信,USB 主机与主机、设备与设备之间是不能通信的。 因此两个正常通信的 USB 接口之间必定有一个主机,一个设备。

在 一个 USB 系统中,仅有一个 USB 主机,但是可以有多个 USB 设备,包括 USB 功能设备和 USB HUB,最多支持 127 个设备。一个 USB 主控制器支持 128 个地址,地址 0 是默认地址,只有在 设备枚举的时候才会使用,地址 0 不会分配给任何一个设备。所以一个 USB 主控制器最多可以 分配 127 个地址。整个 USB 的拓扑结构就是一个分层的金字塔形:

image

USB OTG 就是把USB 接口既可以做 HOST,也可以做 DEVICE。那如何知道应该工作在 HOST 还是 DEVICE 呢?

前面讲mini USB不是讲过多一根ID线嘛,ID线的高低电平表示 USB 口工作在 HOST 还是 DEVICE 模式:

 
  

image

image

USB A这一头没有ID线因此作为从设备,另一头比如typeC, mini-USB有ID线,ID线将电平拉低,表示处于OTG主机模式,用来连接外部从机比如U盘。

image

左侧的为 Mini USB 插座,右边为USB A 插座。

从机(DEVICE)模式:USB_OTG_VBUS 是电源端子,只有插入 Mini USB 线以后 USB_OTG_VBUS 才有效(5V)。插入 Mini USB 线就表示开发板此时要做从机 ,USB_OTG_VBUS 就是电脑供的 5V 电压,由于分压电阻 R111 和 R31 的作用,此时 USB_OTG1_ID 的电压就是 4.5V 左右,很明显这一个高电平。前面我们讲了,当 ID 线为高的时候就表示 OTG 工作在从机模式。

主机(HOST)模式:主机模式下必须将 Mini USB 线拔出来,将 USB 设备插头连接到对应的 USB HOST 接口上。Mini USB 线拔出来以后 USB_OTG_VBUS 就没有电压了,此时 USB_OTG1_ID 线就被 R31 这个 100K 电阻下拉到地,因此 USB_OTG1_ID 线的电压就为 0,当 ID 线为 0 的时 候就表示 OTG 工作在主机模式。

我们软件设置 USB_OTG1_ID 设置为gpio下拉,配成电平,也就是默认 工作在主机(HOST)模式下。当插入mini-USB插线后就工作在从机(DEVICE)模式。

image

USB 设备使用描述符来向主机报告自己的相关属性信息:

image

记录了设备的 USB 版本号、设备类型、VID(厂商 ID)、PID(产品 ID)、设备序列号等。

image

设备描述符的 域定义了一个 USB 设备的配置描述符数量,一个 USB 设备至少有一个。

配置描述符里面包含设备可提供的接口(Interface)数量、配置编号、 供电信息等。

image

字符串描述符是可选的,字符串描述符用于描述一些方便人们阅读的信息,比如制造商、 设备名称啥的。如果一个设备没有字符串描述符,那么其他描述符中和字符串有关的索引值都 必须为 0。

image

wLANGID[0]~wLANGID[x] 指明了设备支持的语言。主机会再次根据自己所需的语言向设备请求字符串描述符,这次会主机会指明要得到的字 符串索引值和语言。

image

配置描述符中指定了该配置下的接口数量,可以提供一个或多个接口,接口描述符用于描 述接口属性。接口描述符中一般记录接口编号、接口对应的端点数量、接口所述的类等。

image

接口描述符定义了其端点数量。端点是设备与主机进行传输的逻辑接口,除了端 点 0 是双向端口,其他的端口都是单向的。

端点描述符描述了传输类型、方向、数据包大小、 端点号等信息。

image

USB 协议定义了 4 种不同的包结构:

  1. 令牌(Token)包
  2. 数据(Data)包
  3. 握手(Handshake)包
  4. 特殊(Special)包

四种包通过包标识符 PID 来区分,PID 共有 8 位,USB 协议使用低 4 位 PID3~PID0,另外的高四位 PID7~PID4 是 PID3~PID0 的取反,传输顺序是 PID0、PID1、PID2、PID3…PID7。

 
  

image

一个完整的包分为多个域,每个包共同的域有以同步域(SYNC)开始,后面紧跟着包标识符 (PID),最终都以包结束(EOP)信号结束。不同的数据包中间位域不同,一般有包目标地址(ADDR)、 包目标端点(ENDP)、数据、帧索引、CRC 等。

下面展开介绍不同包的组成结构:

image

同步域:为 00000001,也 就是连续 7 个 0,后面跟一个 1,如果是高速设备的话就是 31 个 0 后面跟一个 1。

从pid = 0xb4等于1011,0010可以看到是一个SETUP。因为PID[3:0]对应1101。因此PID[7:4]对应0010.

由于传输顺序因此得到0xb4.

PID 后面跟着地址域(ADDR)和端点域(ENDP),为目标设备的地址和端点号。CRC5 域是 5 位 CRC 值,是 ADDR 和 ENDP 这两个域的校验值。最后就是包结束域(EOP),标记本数据包结 束。

其他令牌包的结构和 SETUP 基本类似,只是 SOF 令包中间没有 ADDR 和 ENDP 这两个 域,而是只有一个 11 位的帧号域。

image

PID =0xc3, 这里就是 对应DATA0,PID 值为 0XC3。接下来就是具体的数据,数据完了以后就是 16 位的 CRC 校验值,最 后是 EOP。

image

这是一个ACK 握手包,很简单,首先是 SYNC 同步域,然后就是 ACK 包的 PID,为 0X4B,最后就是 EOP。其他握手包一样的,PID不一样。

端点描述符中 指定了端点的传输类型,一共有 4 种:

控制传输一般用于特定的请求,比如枚举过程就是全部由控制传输来完成的,比如获取描述符、设置地址、设置配置等。

控制传输分为三个阶段:

 
  

数据阶段的所有输入事务必须是同一个方向的,比如都为 IN 或都为 OUT。数据阶段的第一个数据包必须是 DATA1,每 次正确传输以后就在 DATA0 和 DATA1 之间进行切换。数据阶段完成以后就是状态阶段,状态 阶段的传输方向要和数据阶段相反,比如数据阶段为 IN 的话状态阶段就要为 OUT,状态阶段 使用 DATA1 包,比如一个读控制传输格式如下:

image

2.3.1.1 USB 枚举过程

USB 设备与 USB 主机连接以后主机就会对 USB 设备进行枚举,获取设备的描述符信息,主机得到这些信息以后就知道该加载什么样的驱动、如何进行通信等。枚举过程如下:

 
  

同步传输没有握手阶段,即使 数据传输出错了也不会重传。比如于周期性、低时延、数据量大的场合,像音视频传输,这些场合对于时延要求很高,但是不要求数据 100%正确,允许有少量的错误。

同样,批量传输就是用于大批量传输大块数据的,这些数据对实时性没有要求,比如 MSD 类设备(存储设备),U 盘之类的。批量传输 分为批量读(输入)和批量写(输出),如果是批量读的话第一阶段的 IN 令牌包,如果是批量写那 么第一阶段就是 OUT 令牌包。

批量写:

 
  

批量读:

 
  

中断传输适用于传输数据量小、具有周期性并且要求响应速度快的数据,比如键盘、鼠标等。中断的端点会在端点描述符中报告自己的查询时间间隔,对于时间要求严格的设备可以采用中断传输。

下面以具体的芯片来介绍usb控制器。(usb控制器源码待补充)

明显鼠标键盘作为usb从设备,开发板做 USB 主机。像外接 USB 设备,比如 USB 鼠标键盘、USB 转 TTL 串口线、U 盘等设备,都是开发板子做HOST。

USB 鼠标键盘属于 HID 设备,内核已经集成了相应的驱动,NXP 官方提供的 linux 内核默 认已经使能了 USB 鼠标键盘驱动。

 
  

image

使能 USB 键盘和鼠标驱动:

 
  

image

4.1.2.1 测试鼠标

使能后重新编译kernel,得到zImage烧录开发板。启动如果看到如下打印表示USB鼠标。

image

系统检测到了 Logitech(罗技)的鼠标,在 /dev/input 目录下生成一个名为eventX(X=0,1,2,3…)的文件,这个就是我们前面讲的输入子系统, 鼠标和键盘都是作为输入子系统设备的。

我这里是对应/dev/input/event3 这个设备,我们可以hexdump查看鼠标的input原始数据:

image

如果我们适配了GUI 和LCD显示面板,如QT。就可以直接使用鼠标看到鼠标移动踪迹。

4.1.2.2 测试键盘

如果我们适配了GUI 和LCD显示面板,可以直接将LCD作为终端控制台。编辑添加一行代码:

重启开发板,此时屏幕就会作为终端控制台,会有“Please press Enter to activate this console.”这样提示:

image

接上键盘, 输入回车,就可以输入各种命令来执行相应的操作:

image

  1. U 盘使用 SCSI 协议,因此要先使能 Linux 内核中的 SCSI 协议:
 
  

image

  1. 使能 USB Mass Storage
     

image

插上U盘到板子的USB A HOST插槽,打印如下:

image

注意linux下U盘尽量用fat32或者ext3格式。

检测到 U 盘插入,大小为 32GB,对应的设备文件为

 
  

-t 指定挂载所使用的文件系统类型,这里设置为 vfat,也就是 FAT 文件系统,“-o iocharset” 设置硬盘编码格式为 utf8,否则的话 U 盘里面的中文会显示乱码.

如果要弹出U盘:

 
  

前面测试USB都是测试的HOST模式。我们想要开发板测试利用OTG作为DEVICE模式。

前面1.6.2 节讲过:USB OTG 默认工作在主机(HOST)模式下,因此 ID 线应该是低电平。软件需要设置电器属性。

打开设备树:在 节 点的子节点下添加 GPIO1_IO00 引脚信息, 将 GPIO1_IO00 复用为 OTG1 ID,并且设置电气属性为 0X13058,默认下拉, 设备树修改好以后重新编译并用新的设备树启动系统。

 
  

OTG 从机就是将开发板作为一个 USB 设备连接到其他的主机上,这里我们来做两个 USB 从机实验:模拟 U 盘以及 USB 声卡。

4.3.2.1 开发板当成U盘

将开发板当做一个 U 盘,可以将开发板上的 U 盘或者 TF 卡挂载到 PC 上去。

 
  

image

这里我们将USB驱动编译为模块,日常中基本很少这样子用。使用的时候直接输入命令加载驱动模块即可。编译后的模块如下:

 
  

在开发板上插入一个 U 盘,记住这 个 U 盘对应的设备文件,比如我们这里是/dev/sda 和/dev/sda1,以后要将/dev/sda1挂载到 PC 上, 也就是把/dev/sda1 作为模拟 U 盘的存储区域。

image

连接完线后,在板子上insmod驱动:

 
  

如果加载成功的话, PC电脑就会出现一个 U 盘,这个 U 盘就是我们开发板模拟的:

image

我们可以直接在电脑上对这个 U 盘进行读写操作,实际上操作的就是插在开发板上的 U 盘。操作完成以后要退出的话执行如下命令:

 
  

注意U盘一定要是fat32文件系统格式。

注意!不要将开发板上的 EMMC 或者 NAND 作为模拟 U 盘的存储区域,因为 linux 下 EMMC和NAND使用的文件系统一般都是EXT3/EXT4和UBIFS,这些文件系统类型和windows 下的不兼容,如果挂载的话就会在 windows 下提示要你格式化 U 盘。

4.3.2.2 开发板模拟成USB声卡

我们知道电脑主机有些内置声卡效果很差,买了外接USB声卡其实就是利用USB OTG。

同理我们把板子可以当成一个usb从设备,开发板板载了音频解码芯片,因此可以将开发板作为一个外置 USB 声卡。

 
  

image

这里也要将audio部分编译成ko:

 
  

使用 Mini USB 线将开发板与电脑连接起来,并且从板子上安装声卡驱动:

 
  

加载完成以后稍等一会虚拟出一个 USB 声卡,打开电脑的设备管理器,即可找到对应的连接设备:

image

设置 windows,选择音 频输出使用“AC Interface”进行输出:

image

这时候我们的电脑输出声音就从板子扬声器输出了,是不是感觉很有乐趣。

4.3.2.3 USB OTG烧录板子

板子USB烧录,同理也是把板子当成从机device,PC作为host,烧录板子的nand flash or emmc存储。

  • 上一篇: tftp服务器搭建
  • 下一篇: so文件怎么调用
  • 版权声明


    相关文章:

  • tftp服务器搭建2025-06-28 23:30:00
  • python二级报考20242025-06-28 23:30:00
  • gevent eventlet2025-06-28 23:30:00
  • swing的使用2025-06-28 23:30:00
  • linux最好的发行版2025-06-28 23:30:00
  • so文件怎么调用2025-06-28 23:30:00
  • srvctl start asm2025-06-28 23:30:00
  • 跨国网站浏览器2025-06-28 23:30:00
  • 软件测试面试问题2025-06-28 23:30:00
  • 不背单词网址2025-06-28 23:30:00