1. USB Gadget 概述
USB Gadget 是嵌入式 Linux 系统中一种特殊的 USB 设备角色。与传统的 USB Host(主机)不同,Gadget 让嵌入式设备能够作为 USB 外设(Peripheral)连接到另一台主机(如 PC、手机或开发板),并模拟出多种标准 USB 设备功能,例如虚拟网卡、大容量存储、摄像头或串口。
核心概念: USB Gadget 将嵌入式设备从“USB 主控者”转变为“USB 从设备”,使其能够通过 USB 线缆与主机进行数据交互,而无需依赖额外的硬件控制器。
1.1 USB Gadget 与 USB Host 的区别
USB 总线采用主从架构,Host 负责总线调度、枚举和供电,而 Gadget(Peripheral)则响应 Host 的请求。下表列出了两者在嵌入式系统中的关键差异:
| 特性 | USB Host | USB Gadget (Peripheral) |
|---|---|---|
| 角色 | 总线主控者,发起所有传输 | 从设备,响应 Host 请求 |
| 硬件控制器 | EHCI / xHCI 主机控制器 | UDC (USB Device Controller) |
| 软件栈 | USB Core + HCD (Host Controller Driver) | USB Gadget Framework + UDC Driver |
| 典型应用 | 连接 U 盘、鼠标、键盘 | 模拟为网卡、存储设备、摄像头 |
| 供电方向 | 向下游设备供电 (VBUS) | 由 Host 供电或自供电 |
| 枚举过程 | 检测设备插入,发送复位/设置地址 | 等待 Host 枚举,响应描述符请求 |
开发提示: 在嵌入式 Linux 中,同一硬件接口(如 OTG 端口)可通过驱动切换在 Host 和 Gadget 模式之间工作,但运行时角色是互斥的。
1.2 Gadget 在嵌入式系统中的应用场景
USB Gadget 极大地扩展了嵌入式设备的连接能力,使其无需额外硬件即可模拟多种标准 USB 设备。以下是三种最典型的应用场景:
1.2.1 RNDIS(远程网络驱动接口规范)
- 功能: 将嵌入式设备模拟为 USB 以太网适配器。
- 工作原理: 通过 USB 批量传输封装以太网帧,主机端识别为虚拟网卡,实现 TCP/IP 通信。
- 典型场景: 开发板共享网络、IoT 网关配置、设备远程调试。
- 优势: 无需 Wi-Fi 或以太网硬件,即插即用,驱动广泛支持(Windows/Linux/macOS)。
1.2.2 MTP(媒体传输协议)
- 功能: 将嵌入式设备模拟为媒体设备(如手机、相机)。
- 工作原理: 基于 PTP(图片传输协议)扩展,通过 USB 批量传输文件对象和元数据。
- 典型场景: 嵌入式设备与 PC 同步照片、音乐、文档;Android 设备文件传输。
- 优势: 支持双向文件操作,无需卸载存储设备,主机端无需特殊驱动。
1.2.3 UVC(USB 视频类)
- 功能: 将嵌入式设备模拟为 USB 摄像头或视频采集设备。
- 工作原理: 通过 USB 等时传输实时发送视频帧(如 MJPEG、H.264)。
- 典型场景: 嵌入式摄像头模块、工业视觉检测、视频会议设备。
- 优势: 主机端免驱(UVC 驱动内置),支持标准视频应用(如 VLC、Zoom)。
注意事项: UVC 对 USB 带宽和实时性要求较高,嵌入式平台需确保 UDC 支持等时传输,且系统调度延迟可控。
1.3 USB Gadget 软件架构
Linux 内核中的 USB Gadget 子系统采用分层设计,从硬件到用户空间共分为四层。下图展示了其核心架构:
1.4 Gadget 工作流程简述
一个典型的 USB Gadget 设备从插入到正常工作的流程如下:
- 物理连接: 嵌入式设备通过 USB 线缆连接到 Host(如 PC)。
- VBUS 检测: UDC 检测到 VBUS 电平,触发中断,通知 Gadget 框架。
- Host 枚举: Host 发送复位信号、设置地址、请求设备描述符、配置描述符等。
- 描述符响应: Gadget 功能驱动通过 UDC 返回对应的描述符数据(VID/PID、接口、端点等)。
- 配置选择: Host 选择一个配置(Configuration),Gadget 激活对应的接口和端点。
- 数据传输: 根据功能类型(批量/中断/等时),Host 与 Gadget 开始双向数据通信。
关键点: 整个枚举过程由 Host 主导,Gadget 处于被动响应状态。Gadget 驱动必须正确实现描述符回调,否则 Host 无法识别设备。
1.5 常见 Gadget 功能对比
| 功能 | 内核模块 | 传输类型 | 典型带宽 | 主机端驱动 |
|---|---|---|---|---|
| RNDIS | g_ether.ko | 批量 (Bulk) | ~40 MB/s (USB 2.0) | RNDIS 驱动 (内置) |
| MTP | g_mtp.ko | 批量 (Bulk) | ~30 MB/s (USB 2.0) | MTP 驱动 (Win)/libmtp (Linux) |
| UVC | g_uvc.ko | 等时 (Isochronous) | ~200-400 Mbps (USB 2.0) | UVC 驱动 (内置) |
| 大容量存储 | g_mass_storage.ko | 批量 (Bulk) | ~35 MB/s (USB 2.0) | USB 大容量存储驱动 (内置) |
| 串口 (ACM) | g_serial.ko | 批量 (Bulk) | ~1 MB/s | CDC ACM 驱动 (内置) |
选型建议: 如果嵌入式设备需要同时提供多种功能(如 RNDIS + MTP),可以使用 Composite Gadget(g_multi.ko)将多个功能组合到同一个 USB 设备中,但需注意端点数量限制。