2. Linux USB子系统架构:USB主机侧与设备侧、USB Core、HCD、UDC、Gadget API分层

在深入UVC Gadget驱动开发之前,必须理解Linux USB子系统的整体架构。USB子系统采用分层的模块化设计,既支持传统的USB主机侧(Host Side),也支持USB设备侧(Device Side/Gadget Side)。这种对称架构使得Linux既能作为USB主机连接外设,也能作为USB设备被其他主机识别。

2.1 USB子系统全景架构

下图展示了Linux USB子系统的核心分层结构,清晰区分了主机侧与设备侧的对应关系:

Linux USB子系统分层架构 USB 主机侧 (Host Side) USB 设备侧 (Device Side) USB Device Driver (UVC, HID, Mass Storage...) USB设备驱动层 USB Core (usbcore.ko) USB核心层:协议管理、总线、设备枚举 HCD (Host Controller Driver) 主机控制器驱动:EHCI / xHCI / OHCI / UHCI USB Host Controller (硬件) USB主机控制器硬件 Gadget Function Driver (UVC Gadget...) Gadget功能驱动层 USB Gadget API (Gadget Core) Gadget核心层:UDC抽象、端点管理 UDC (USB Device Controller) Driver 设备控制器驱动:DWC2 / DWC3 / ChipIdea USB Device Controller (硬件) USB设备控制器硬件 USB 物理总线 💡 主机侧与设备侧通过USB Core和Gadget API实现对称抽象,UVC Gadget位于设备侧最上层 开发UVC Gadget驱动时,主要与Gadget API和UDC驱动交互

2.2 USB主机侧架构详解

USB主机侧是Linux最成熟的USB子系统部分,负责管理连接到系统的所有USB外设。其分层结构自底向上包括:

2.2.1 主机控制器硬件 (Host Controller)

位于最底层的物理硬件,负责USB总线的电气信号传输。常见的主机控制器标准包括:

标准 全称 速度 典型应用
UHCI Universal Host Controller Interface USB 1.1 (12 Mbps) Intel/VIA芯片组,软件开销大
OHCI Open Host Controller Interface USB 1.1 (12 Mbps) 非Intel平台,硬件开销大
EHCI Enhanced Host Controller Interface USB 2.0 (480 Mbps) 高速USB设备
xHCI eXtensible Host Controller Interface USB 3.x (5/10/20 Gbps) 现代平台,兼容所有速度

2.2.2 HCD (Host Controller Driver)

HCD是主机控制器驱动的内核模块,直接操作硬件寄存器,向上层提供统一的接口。Linux内核中对应的驱动文件位于 drivers/usb/host/ 目录下:

drivers/usb/host/
├── ehci-hcd.c      # EHCI主机控制器驱动
├── ohci-hcd.c      # OHCI主机控制器驱动
├── uhci-hcd.c      # UHCI主机控制器驱动
├── xhci-hcd.c      # xHCI主机控制器驱动
└── ...

2.2.3 USB Core (usbcore.ko)

USB Core是主机侧的核心层,实现了USB协议栈的通用逻辑:

  • 总线管理:维护USB总线拓扑结构,处理设备热插拔
  • 设备枚举:分配地址、读取描述符、配置设备
  • 数据传输:管理URB(USB Request Block)的提交与完成
  • 驱动匹配:根据设备描述符匹配对应的USB设备驱动

关键概念:URB — USB Request Block是USB主机侧数据传输的核心数据结构。所有与USB设备的数据交换都通过URB进行,URB包含传输类型(控制/批量/中断/等时)、目标端点、数据缓冲区、回调函数等信息。

2.2.4 USB设备驱动层

最上层的设备驱动实现具体的USB设备功能,例如UVC摄像头驱动、USB存储驱动、HID驱动等。这些驱动通过USB Core提供的API与硬件交互。

2.3 USB设备侧架构详解

设备侧(Gadget侧)是Linux USB子系统的另一面,使嵌入式设备能够模拟USB外设。其分层结构与主机侧对称但方向相反:

2.3.1 UDC硬件 (USB Device Controller)

UDC是嵌入式SoC内部集成的USB设备控制器硬件,负责处理USB协议的数据包收发。常见的UDC硬件包括:

  • DWC2 (DesignWare USB 2.0 OTG) — 广泛用于STM32、Allwinner等平台
  • DWC3 (DesignWare USB 3.0) — 用于高通、瑞芯微等高端平台
  • ChipIdea — NXP i.MX系列常用
  • FUSB — 某些FPGA或ASIC实现

2.3.2 UDC驱动层

UDC驱动直接操作UDC硬件寄存器,实现端点管理、DMA传输、中断处理等底层功能。Linux内核中对应的驱动位于 drivers/usb/gadget/udc/:

drivers/usb/gadget/udc/
├── dwc2.c          # DWC2 UDC驱动
├── dwc3.c          # DWC3 UDC驱动
├── chipidea/       # ChipIdea UDC驱动
├── fsl_qe_udc.c    # Freescale QE UDC
└── ...

2.3.3 Gadget API层 (Gadget Core)

Gadget API是设备侧的核心抽象层,相当于主机侧的USB Core。它提供了:

  • UDC抽象:统一不同UDC硬件的操作接口
  • 端点管理:分配、配置、释放USB端点
  • 请求管理:管理USB Request(类似主机侧的URB)
  • 配置管理:处理USB配置、接口、备用设置

开发提示:Gadget API的核心数据结构是 struct usb_gadget 和 struct usb_ep。UVC Gadget驱动通过这两个结构体与底层UDC交互,无需关心具体硬件细节。

2.3.4 Gadget Function驱动层

最上层是Gadget功能驱动,实现具体的USB设备功能。常见的Gadget功能驱动包括:

功能驱动 模拟设备 内核模块
g_ether.ko USB网卡 (RNDIS/ECM) drivers/usb/gadget/function/f_ecm.c
g_mass_storage.ko USB存储设备 drivers/usb/gadget/function/f_mass_storage.c
g_serial.ko USB串口 drivers/usb/gadget/function/f_serial.c
g_uvc.ko USB摄像头 (UVC) drivers/usb/gadget/function/f_uvc.c
g_hid.ko USB HID设备 drivers/usb/gadget/function/f_hid.c

2.4 主机侧与设备侧的关键差异

理解两侧的差异对于UVC Gadget开发至关重要:

对比维度 主机侧 (Host) 设备侧 (Gadget)
角色 总线主控,发起所有传输 从设备,响应主机请求
数据传输 通过URB提交请求 通过usb_request提交数据
枚举过程 主动分配地址、读取描述符 被动响应主机的枚举请求
核心层 USB Core (usbcore.ko) Gadget API (udc-core.ko)
驱动目录 drivers/usb/host/ drivers/usb/gadget/
电源管理 管理下游设备挂起/唤醒 响应主机的挂起/唤醒信号

2.5 UVC Gadget在架构中的位置

UVC Gadget驱动位于设备侧的最上层,其调用关系如下:

UVC Gadget驱动调用栈 UVC Gadget Function (f_uvc.c) Gadget API (gadget.ko / udc-core.ko) UDC Driver (dwc2.ko / dwc3.ko) USB Device Controller (硬件) 用户空间 内核空间 硬件层

重要提醒:UVC Gadget驱动开发的核心工作集中在最上层(f_uvc.c),但必须理解下层Gadget API和UDC驱动的接口约定。常见的开发陷阱包括:端点类型选择错误(UVC需要等时端点)、数据传输大小未对齐、描述符配置与硬件能力不匹配等。

2.6 关键数据结构关系

在设备侧,核心数据结构之间的关联关系如下:

struct usb_gadget          // 代表一个UDC设备
├── struct usb_ep *ep0     // 控制端点0
├── struct usb_ep *in_ep   // IN端点(主机到设备方向)
├── struct usb_ep *out_ep  // OUT端点(设备到主机方向)
└── struct usb_gadget_driver *driver  // 当前绑定的Gadget驱动

struct usb_gadget_driver   // Gadget功能驱动
├── char *function_name    // 功能名称,如 "uvc"
├── int (*bind)(...)       // 绑定回调:配置端点、分配资源
├── int (*unbind)(...)     // 解绑回调
├── int (*setup)(...)      // 处理标准请求(如SET_CONFIGURATION)
└── void (*disconnect)(...) // 断开连接回调

struct usb_request         // USB请求(类似主机侧URB)
├── struct usb_ep *ep      // 所属端点
├── void *buf              // 数据缓冲区
├── unsigned int length    // 数据长度
├── void (*complete)(...)  // 完成回调函数
└── int status             // 传输状态

2.7 本章小结

Linux USB子系统的分层架构为UVC Gadget驱动开发提供了清晰的抽象边界:

  • 主机侧:USB Core + HCD + 设备驱动,适用于开发USB主机功能
  • 设备侧:Gadget API + UDC驱动 + 功能驱动,适用于开发USB设备功能
  • UVC Gadget:位于设备侧最上层,通过Gadget API与UDC交互,模拟USB摄像头
  • 核心接口:usb_gadget、usb_ep、usb_request 是设备侧编程的三个核心数据结构