1. USB 基础概念

USB(Universal Serial Bus,通用串行总线)自 1996 年问世以来,已成为嵌入式系统与主机之间最通用的连接标准。在进入 Gadget 驱动开发之前,必须透彻理解 USB 的物理拓扑、角色分工、速度等级以及协议栈的分层架构。本章从这四个维度构建 USB 的知识骨架,为后续的 Gadget 驱动实现打下坚实基础。

1.1 USB 总线拓扑结构

USB 采用星型-级联拓扑,由一个主机(Host)和最多 127 个设备(Device)组成。主机通过根集线器(Root Hub)引出总线,设备可以直连主机,也可以通过集线器(Hub)扩展层级。USB 规范规定最多允许 7 层(Tier),包括根集线器在内。

关键点:USB 拓扑中不允许环路,所有通信必须经过主机调度。设备之间不能直接通信,必须由主机作为仲裁者。
USB 总线拓扑结构(星型-级联) USB 主机 (Host) 根集线器 (Root Hub) 设备 A (Tier 1) 集线器 (Hub) 设备 B (Tier 1) 设备 C (Tier 2) 设备 D (Tier 2) 设备 E (Tier 3) 最大 7 层(Tier),最多 127 个设备,不允许环路

1.2 主机与设备角色

USB 总线是主从架构,角色严格区分:

角色 职责 典型硬件 驱动类型
主机(Host) 调度总线、发起传输、管理枚举、分配地址 PC、树莓派、OTG 主模式 Host Controller Driver (HCD)
设备(Device) 响应主机请求、报告描述符、传输数据 U 盘、键盘、嵌入式 Gadget Function Driver / Gadget Driver
集线器(Hub) 端口扩展、检测连接/断开、电源管理 USB Hub 芯片 Hub Driver
OTG 双角色 可在 Host 与 Device 间切换 手机、嵌入式开发板 OTG Driver + Gadget
Gadget 视角:在嵌入式 Linux 中,我们通常将开发板配置为 Device 角色,通过 Gadget 驱动模拟成 U 盘、串口、网卡或音频设备。OTG 硬件允许同一端口在 Host 和 Device 之间动态切换。

1.3 USB 速度等级

USB 规范定义了四种主要速度等级,不同速度在电气信号、线缆长度、协议细节上均有差异:

速度等级 缩写 理论速率 信号编码 最大线缆长度 引入版本
低速 LS 1.5 Mbps NRZI + 位填充 5 m USB 1.0
全速 FS 12 Mbps NRZI + 位填充 5 m USB 1.1
高速 HS 480 Mbps NRZI + 位填充 + 微帧 5 m USB 2.0
超高速 SS 5 Gbps / 10 Gbps / 20 Gbps 8b/10b (Gen1) / 128b/132b (Gen2) 3 m USB 3.x
USB 速度等级对比 低速 (LS) 1.5 Mbps USB 1.0 全速 (FS) 12 Mbps USB 1.1 高速 (HS) 480 Mbps USB 2.0 超高速 (SS) 5/10/20 Gbps USB 3.x 速率递增 → Gadget 驱动需要根据硬件能力选择速度等级,高速设备必须兼容全速 USB 3.0 超高速使用独立物理通道,与 USB 2.0 信号共存
开发注意:在 Gadget 驱动中,设备描述符(Device Descriptor)的 bcdUSB 字段声明设备支持的最高 USB 版本。如果声明为 0x0200(USB 2.0),主机将以高速模式枚举;如果声明为 0x0110(USB 1.1),则降级为全速。错误的速度声明会导致枚举失败或性能严重下降。

1.4 USB 协议栈分层

USB 协议栈采用分层架构,从物理信号到应用数据逐层封装。理解分层是编写 Gadget 驱动的关键前提。

USB 协议栈分层架构 应用层(Application Layer) 设备类层(Device Class Layer) HID / Mass Storage / CDC ACM / RNDIS / Audio / Video 协议层(Protocol Layer) 控制传输 / 批量传输 / 中断传输 / 等时传输 链路层(Link Layer) 包定界 / CRC / 握手 / 令牌包 / 数据包 物理层(Physical Layer) NRZI 编码 / 差分信号 D+ D- / 电气特性 Gadget 驱动主要工作在设备类层和协议层,通过 Linux USB Gadget API 与链路层交互 物理层和链路层由 USB 控制器硬件和 UDC(USB Device Controller)驱动处理

各层职责详解

层次 职责 Gadget 驱动关注点
物理层 差分信号传输、NRZI 编码、位填充、电气特性 硬件兼容性、速度协商
链路层 包定界、CRC 校验、握手协议、令牌/数据/握手包 端点(Endpoint)配置、包大小
协议层 四种传输类型:控制、批量、中断、等时 选择传输类型、设置端点属性
设备类层 定义标准设备类协议(HID、MSC、CDC 等) 实现类特定描述符和请求处理
应用层 用户态应用程序通过设备节点访问 USB 功能 与用户态交互接口(/dev 节点)

Linux USB Gadget 软件栈

在 Linux 内核中,Gadget 驱动位于设备类层和协议层之间,通过 UDC(USB Device Controller)驱动与硬件交互。以下是典型的软件分层:

Linux USB Gadget 软件栈 用户空间应用程序(User Space) 内核空间(Kernel Space) Gadget Function 驱动(g_serial / g_ether / g_mass_storage) UDC 驱动(USB Device Controller Driver) USB 硬件控制器(DWC2 / Chipidea / Synopsys)
Gadget 驱动开发核心:开发者主要编写 Gadget Function 驱动,通过 Linux 内核提供的 usb_gadget 框架注册端点、处理请求、实现类特定协议。UDC 驱动通常由芯片厂商提供,开发者只需配置设备树或平台数据即可。

关键数据结构预览

在后续章节中,我们将频繁操作以下内核数据结构。这里先列出名称和用途,建立初步印象:

数据结构 定义位置 用途
struct usb_gadget include/linux/usb/gadget.h 代表一个 USB 设备控制器实例
struct usb_ep include/linux/usb/gadget.h 代表一个端点(Endpoint)
struct usb_request include/linux/usb/gadget.h 代表一次 USB 数据传输请求
struct usb_composite_dev include/linux/usb/composite.h 复合设备框架,管理多个 Function
struct usb_function include/linux/usb/composite.h 代表一个 USB 功能(如串口、网卡)