1. USB Gadget 框架概述

USB Gadget 框架是 Linux 内核中用于实现 设备端(Device/Peripheral) USB 功能的软件基础设施。它允许嵌入式设备(如开发板、手机、IoT 网关)通过 USB 接口模拟成键盘、鼠标、U 盘、网卡、串口等标准外设,从而与主机(Host)进行通信。

核心概念:在 USB 协议中,Host 端(如 PC)使用 usbcore 和 HCD(Host Controller Driver)管理外设;而 Device 端则使用 Gadget 框架实现“被枚举”和“功能模拟”。Gadget 框架是 Linux 在嵌入式场景下实现 USB 外设功能的核心支撑。

1.1 Gadget 框架在 Linux 内核中的位置

Gadget 框架位于 Linux 内核的 drivers/usb/gadget/ 目录下,与 Host 端驱动栈并列,但运行在完全不同的角色模式中。下图展示了 Gadget 框架在整个 USB 软件栈中的层级关系:

Linux USB Gadget 框架在内核中的位置 Linux USB 双角色软件栈 — Gadget 框架位置 Host 端(主机侧) 用户态应用 / libusb USB 核心层 (usbcore) HCD (Host Controller Driver) USB 控制器硬件 (Host) Device 端(设备侧) Gadget Function 驱动 (如:g_ether、g_serial、g_mass_storage) Gadget 核心层 (udc-core) UDC 驱动 (USB Device Controller) USB 控制器硬件 (Device) USB 总线 Gadget 框架运行在 Device 端,与 Host 端 usbcore 对称但角色相反 Function 驱动实现具体外设逻辑,UDC 驱动操作底层控制器硬件
关键对比:Host 端使用 usbcore + HCD 管理外设;Device 端使用 udc-core + UDC 驱动模拟外设。两者通过 USB 总线连接,角色完全对称。

1.2 Gadget 框架的核心作用

Gadget 框架解决了嵌入式设备“如何被主机识别并通信”的问题。其核心作用可归纳为以下四点:

作用维度 具体说明 典型场景
设备枚举 响应 Host 的枚举请求,上报设备描述符、配置描述符、接口描述符等,完成 USB 设备识别 PC 插入开发板后识别为“Linux File-Stor Gadget”
功能模拟 将硬件 USB 控制器抽象为多种标准外设功能,如网卡、串口、音频、HID 等 开发板模拟 USB 以太网卡(RNDIS / ECM)
数据传输 管理 USB 端点(Endpoint)的分配与数据传输,支持控制、批量、中断、等时四种传输类型 批量端点传输网络数据包,中断端点传输 HID 报告
复合设备 支持单个 USB 连接同时提供多种功能(如网卡 + 串口 + 存储),通过复合配置实现 工业设备同时提供虚拟网卡和调试串口

1.3 Gadget 框架的基本架构

Gadget 框架采用 分层 + 模块化 设计,从上到下依次为:Function 驱动层 → Gadget 核心层 → UDC 驱动层。各层职责清晰,通过标准 API 进行交互。

USB Gadget 框架分层架构图 USB Gadget 框架分层架构 Function 驱动层(功能实现) g_ether.ko | g_serial.ko | g_mass_storage.ko | g_hid.ko | g_audio.ko 实现具体外设逻辑:描述符定义、端点管理、数据收发回调 Gadget 核心层(框架核心) udc-core.c | configfs.c | ep0.c | usb_gadget_probe_driver() 提供 Gadget / UDC 注册、端点分配、控制传输处理、复合设备管理 UDC 驱动层(硬件抽象) dwc2_udc.c | dwc3_gadget.c | chipidea_udc.c | musb_gadget.c 操作具体 USB 控制器寄存器,处理中断,管理端点 FIFO USB 控制器硬件 DWC2 | DWC3 | ChipIdea | MUSB | Renesas USB 向上提供功能接口 向下屏蔽硬件差异

1.4 各层职责详解

1.4.1 Function 驱动层

Function 驱动是 Gadget 框架中最接近应用逻辑的层次。每个 Function 驱动实现一种具体的 USB 外设功能,例如:

  • g_ether:实现 USB 以太网卡(支持 ECM、RNDIS、EEM 等协议)
  • g_serial:实现 USB 虚拟串口(ACM 类)
  • g_mass_storage:实现 USB 大容量存储设备(U 盘)
  • g_hid:实现 USB HID 设备(键盘、鼠标、游戏手柄)
  • g_audio:实现 USB 音频设备(UAC)

Function 驱动需要完成:定义设备/配置/接口/端点描述符、注册端点、实现数据传输回调函数。

1.4.2 Gadget 核心层

核心层是框架的“中枢神经系统”,主要提供以下能力:

核心模块 文件 职责
UDC 核心 udc-core.c 管理 UDC 驱动注册/注销,处理绑定/解绑事件
端点 0 处理 ep0.c 处理控制传输(标准请求 + 类请求)
ConfigFS 接口 configfs.c 提供用户态配置接口,支持动态组合功能
复合设备 composite.c 支持多个 Function 组合成一个复合设备

1.4.3 UDC 驱动层

UDC(USB Device Controller)驱动是直接操作硬件控制器的底层驱动。不同 SoC 厂商的 USB 控制器差异较大,因此 UDC 驱动需要针对具体硬件实现:

  • 端点寄存器配置与 FIFO 管理
  • 中断处理(连接/断开、端点传输完成、复位等)
  • DMA 传输支持(如 DWC3 支持 Scatter-Gather DMA)
  • 电源管理(挂起/恢复)
开发注意事项:UDC 驱动是硬件相关的,通常由 SoC 厂商提供或主线内核已支持。在开发 Gadget Function 驱动时,一般不需要修改 UDC 驱动层,只需在 Function 层实现业务逻辑即可。但如果遇到硬件兼容性问题,可能需要深入 UDC 驱动进行调试。

1.5 Gadget 框架的数据流

理解数据在 Gadget 框架中的流动路径,对后续开发虚拟网卡驱动至关重要。以 USB 虚拟网卡为例,数据流如下:

Gadget 框架数据流(以虚拟网卡为例) Gadget 框架数据流 — USB 虚拟网卡发送路径 网络协议栈 TCP/IP 层 g_ether 驱动 打包成 USB 帧 Gadget 核心 端点调度 UDC 驱动 写 FIFO USB 总线 传输到 Host 硬件中断 数据从网络协议栈 → Function 驱动 → Gadget 核心 → UDC 驱动 → USB 总线 接收路径方向相反,由 UDC 中断触发上行

1.6 本章小结

USB Gadget 框架是 Linux 设备端 USB 功能的核心基础设施,其分层架构(Function 层 → 核心层 → UDC 层)实现了功能与硬件的解耦。在本课程后续章节中,我们将深入 g_ether 驱动的实现细节,从零开始构建一个完整的 USB 虚拟网卡驱动。

关键要点回顾:
  • Gadget 框架位于 drivers/usb/gadget/,与 Host 端 usbcore 对称
  • Function 驱动实现具体外设逻辑,是开发者的主要工作区域
  • 核心层提供 UDC 管理、端点分配、控制传输等通用服务
  • UDC 驱动操作硬件,通常由 SoC 厂商提供
  • 数据流在四层之间单向传递,接收路径由硬件中断触发