1. USB Gadget 框架概述

USB Gadget 子系统是 Linux 内核中用于让嵌入式设备模拟 USB 外设(如键盘、鼠标、U盘、网卡)的核心框架。与 USB Host 侧不同,Gadget 侧负责实现设备端(Device/Peripheral)的功能。理解其分层架构是进行驱动调试与中断端点通信的基础。

核心概念: Linux USB Gadget 子系统将硬件控制、协议处理与功能实现解耦为三层:UDC 驱动层、Gadget 功能驱动层、以及上层的配置接口(Legacy 或 ConfigFS)。

1.1 三层架构总览

整个子系统从上到下分为三个层次,每一层职责明确,通过标准 API 进行交互。下图展示了这三层之间的调用关系与数据流。

USB Gadget 三层架构图 USB Gadget 子系统三层架构 配置接口层 ConfigFS (用户空间配置) | Legacy (内核模块绑定) Gadget 功能驱动层 g_serial.ko | g_ether.ko | g_mass_storage.ko | f_hid.ko 实现具体 USB 功能(CDC ACM、ECM、HID、MSC) UDC 驱动层 dwc2.ko | dwc3.ko | chipidea.ko | musb.ko 直接操作 USB 控制器寄存器,处理端点(Endpoint)硬件 说明: 上层通过 usb_gadget_probe_driver() 向下注册,下层通过 usb_ep_queue() 向上提交数据。 中断端点通信主要发生在 Gadget 功能驱动与 UDC 驱动之间。

1.2 UDC 驱动层(底层)

UDC(USB Device Controller)驱动是直接与硬件 USB 控制器交互的软件模块。它负责管理 USB 控制器的寄存器、端点(Endpoint)资源、以及处理 USB 总线上的标准事件(如复位、挂起、SETUP 包)。

  • 职责: 初始化硬件、分配端点、处理中断、收发数据包。
  • 关键结构体: struct usb_gadget 代表一个 USB 设备控制器;struct usb_ep 代表一个端点。
  • 常见驱动: dwc2(常用于树莓派、Allwinner)、dwc3(高通、TI)、chipidea(NXP i.MX)、musb(TI OMAP)。
  • 调试入口: 通过 /sys/kernel/debug/usb/<udc-name>/ 查看端点状态和请求队列。
调试提示: 当遇到端点通信无响应时,首先检查 UDC 驱动是否成功绑定。执行 cat /sys/kernel/debug/usb/devices 查看 UDC 状态,确认控制器是否进入配置状态。

1.3 Gadget 功能驱动层(中间层)

功能驱动实现了具体的 USB 设备功能。例如,g_serial 实现串口功能,g_ether 实现以太网功能,g_mass_storage 实现 U 盘功能。这些驱动通过调用 UDC 层提供的 API 来操作端点。

功能驱动模块 模拟设备类型 使用的端点类型 典型应用场景
g_serial.ko CDC ACM 串口 Bulk IN / Bulk OUT 嵌入式设备调试、AT 命令
g_ether.ko CDC ECM / RNDIS 网卡 Bulk IN / Bulk OUT 设备网络共享、IoT 网关
g_mass_storage.ko USB 大容量存储设备 Bulk IN / Bulk OUT U 盘、读卡器
f_hid.ko HID 设备(键盘/鼠标) Interrupt IN 人机交互设备、自定义按键
f_uac1/2.ko USB 音频设备 Isochronous USB 麦克风、扬声器
注意: 中断端点(Interrupt Endpoint)主要用于 HID 类设备或需要低延迟通知的场景。在调试中断端点通信时,务必确认功能驱动正确配置了端点描述符中的 bInterval 字段,该字段决定了主机轮询间隔。

1.4 ConfigFS 与 Legacy 模式对比

上层配置接口决定了如何将功能驱动绑定到 UDC 控制器上。Legacy 模式是旧有的内核模块绑定方式,而 ConfigFS 是当前推荐的用户空间配置方式。

ConfigFS vs Legacy 配置流程对比 ConfigFS 与 Legacy 模式配置流程对比 Legacy 模式(旧) 1. 编译内核时选择 g_xxx 模块 2. 模块加载时自动绑定 UDC 3. 功能固定,无法运行时动态切换 ConfigFS 模式(新) 1. 挂载 configfs 文件系统 2. 在 /sys/kernel/config/usb_gadget/ 下创建目录 3. 动态创建/绑定功能,支持多配置 关键差异总结: • 灵活性:ConfigFS 支持运行时动态组合功能(如同时模拟键盘+U盘),Legacy 只能使用预编译的单一功能。 • 调试便利性:ConfigFS 无需重新编译内核模块即可切换功能,适合开发调试阶段。 • 中断端点支持:两者均支持,但 ConfigFS 允许更精细地控制端点描述符参数。

1.5 如何选择配置方式

下表从开发调试和生产部署两个维度,给出了选择建议。

场景 推荐模式 理由
快速原型验证 Legacy(g_xxx 模块) 加载模块即用,无需编写配置脚本
多功能复合设备 ConfigFS 支持多配置、多接口组合,灵活性强
中断端点调试 ConfigFS 可单独加载 f_hid 功能,配合 usbmon 抓包分析
产品量产固件 ConfigFS 或 定制 Legacy ConfigFS 更通用;Legacy 可减少用户空间依赖