3. 硬件平台与UDC:UDC的作用、常见硬件与数据手册解读
在USB Gadget驱动栈中,UDC(USB Device Controller)是连接软件协议栈与物理USB端口的硬件桥梁。理解UDC的架构、寄存器模型和中断机制,是完成Gadget驱动移植适配的前提。本节将系统梳理UDC的核心作用、主流硬件IP核的差异,以及如何从数据手册中提取关键移植信息。
3.1 UDC在USB Gadget系统中的角色
UDC位于USB设备侧(Device Side),负责处理USB总线上的包传输、协议解析和状态机维护。在Linux Gadget框架中,UDC驱动向上通过usb_gadget_ops结构体向Gadget Function层提供标准接口,向下直接操作硬件寄存器。
下图展示了UDC在完整Gadget软件栈中的位置与数据流向:
从图中可以看出,UDC驱动层是唯一直接与硬件寄存器打交道的模块。移植适配时,开发者需要根据SoC集成的UDC IP核类型,选择或修改对应的驱动文件。
3.2 常见UDC硬件IP核对比
嵌入式领域主流的UDC IP核主要有三种:Synopsys DWC2、Synopsys DWC3和NXP Chipidea。它们在端点数量、DMA支持、USB协议版本和驱动复杂度上存在显著差异。
| 特性 | DWC2 | DWC3 | Chipidea |
|---|---|---|---|
| USB协议版本 | USB 2.0 (HS/FS) | USB 3.0/3.1 (SS) | USB 2.0 (HS/FS) |
| 端点数量 | 最多 16 个 (IN+OUT) | 最多 32 个 (双向) | 最多 15 个 (双向) |
| DMA支持 | 内部DMA / 从模式 | 内置DMA控制器 | 无内置DMA (依赖外部) |
| FIFO架构 | 专用FIFO (每端点) | 共享FIFO池 | 双端口RAM |
| Linux驱动 | drivers/usb/dwc2/ | drivers/usb/dwc3/ | drivers/usb/chipidea/ |
| 典型SoC | Rockchip RK3288, Allwinner H3 | TI AM57x, i.MX8M | NXP i.MX6, i.MX7 |
3.3 DWC2硬件架构与寄存器要点
DWC2是应用最广泛的USB 2.0 Device控制器。其内部结构分为主机接口层、FIFO管理单元和端点控制逻辑三部分。移植时最常操作的寄存器包括:
- GOTGCTL (OTG Control & Status):控制设备/主机模式切换,复位后需配置为Device模式。
- GAHBCFG (AHB Configuration):使能全局DMA、设置突发传输长度。
- DIEPCTLx / DOEPCTLx (Device Endpoint Control):每个端点的类型、最大包大小、使能控制。
- DIEPTSIZx / DOEPTSIZx (Transfer Size):设置传输数据长度、包计数和PID。
- GINTSTS / GINTMSK (Global Interrupt):中断状态与屏蔽寄存器,处理SOF、复位、连接断开等事件。
下图展示了DWC2内部模块与Linux驱动层的对应关系:
3.4 DWC3硬件架构与关键差异
DWC3是USB 3.0控制器,其架构相比DWC2有本质变化:
- 双向端点架构:每个物理端点同时支持IN和OUT方向,不再区分DIEP/DOEP。
- 共享FIFO池:所有端点共用全局FIFO空间,通过
DWC3_GTXFIFOSIZ寄存器动态分配。 - TRB描述符链:数据传输基于Transfer Request Block(TRB)链表,支持Scatter-Gather DMA。
- 事件中断机制:所有完成事件通过Event Ring上报,驱动轮询Event Buffer。
status字段在硬件写入后驱动才能读取。如果SoC的DMA一致性映射配置不当,会导致描述符读取到脏数据。移植时务必检查dma_alloc_coherent的调用参数。
3.5 Chipidea硬件特点
Chipidea(现为NXP IP)常见于i.MX系列SoC。其特点包括:
- 无内置DMA:数据传输依赖CPU直接读写FIFO(PIO模式),或通过SoC的IDMAC(外部DMA控制器)。
- 双端口RAM架构:端点FIFO通过双端口RAM实现,驱动需配置
PORTSC和ENDPTPRIME寄存器。 - 中断聚合:支持多个端点中断合并为一次中断,减少CPU负载。
Linux驱动中,Chipidea的UDC驱动位于drivers/usb/chipidea/udc.c,其核心数据结构为ci_hdrc,包含端点数组、DMA池和中断处理函数指针。
3.6 硬件数据手册解读要点
移植UDC驱动时,数据手册(Datasheet / Reference Manual)是唯一权威参考。以下是从手册中提取关键信息的步骤:
- 确认UDC IP核版本:查找SoC手册的“USB Controller”章节,确认IP核是DWC2、DWC3还是Chipidea,以及其版本号(如DWC2_otg 2.94a)。
- 寄存器基地址与内存映射:记录UDC寄存器的基地址(如
0x30000000),以及是否支持AHB/AXI总线接口。 - 端点配置寄存器:找到每个端点的控制、状态、传输大小寄存器的偏移地址和位域定义。
- 中断向量与触发方式:确认UDC中断号(IRQ number),以及中断是电平触发还是边沿触发。
- 时钟与复位控制:查找UDC模块的时钟门控(Clock Gating)和复位控制寄存器,确保驱动能正确使能时钟。
- DMA描述符格式:如果使用DMA,手册中必须有描述符结构体定义(如TRB、DMA Descriptor),需与驱动中的结构体严格对齐。
| 信息类别 | 手册章节 | 移植用途 |
|---|---|---|
| IP核版本 | “Overview” / “Features” | 选择对应驱动版本 |
| 寄存器基地址 | “Memory Map” | ioremap / devm_ioremap_resource |
| 端点寄存器偏移 | “Endpoint Registers” | 定义hw_params结构体 |
| 中断号 | “Interrupt Controller” | request_irq / devm_request_irq |
| 时钟门控 | “Clock Tree” / “CCM” | clk_prepare_enable |
| DMA描述符 | “DMA Engine” / “TRB” | 定义dma_async_tx_descriptor |
GSNPSID、DWC3的GSNPSID、Chipidea的ID),验证硬件访问通路是否正确。这一步可以提前暴露地址映射或时钟配置问题。
3.7 本章小结
UDC是Gadget驱动移植的核心硬件依赖。开发者需要:
- 明确目标SoC使用的UDC IP核类型(DWC2/DWC3/Chipidea)。
- 理解不同IP核在端点架构、DMA支持和FIFO管理上的差异。
- 掌握从数据手册中提取寄存器、中断、时钟和DMA描述符信息的方法。
- 在驱动移植前,通过寄存器读取验证硬件通路是否正常。