USB 软件架构全解:驱动模型、协议栈与开发机制详解

支持作者,点击京东购买作者创作书籍《Yocto项目实战教程:高效定制嵌入式Linux系统》

延续《USB 硬件原理全解》篇章,本文将聚焦于 USB 的软件架构、协议栈实现、驱动开发流程以及主从模式下的实际驱动设计逻辑,完整梳理 Linux 中 USB 子系统的核心实现机制,帮助开发者深入理解 USB 软件层的技术全貌。


一、USB 软件架构整体概览

USB 软件在 Linux 内核中是一个独立的子系统,包含以下几个关键层次:

用户空间
├── libusb / 文件系统节点(/dev/ttyUSBx, /dev/sda)
内核空间
├── USB 类驱动(Class Driver)
├── USB Core 层(设备管理、匹配、配置)
├── 主机控制器驱动(HCD)
└── Gadget 设备控制器驱动(UDC)

在这里插入图片描述


二、主机模式(Host)驱动结构

在这里插入图片描述

2.1 主机控制器驱动(HCD)

  • 管理 SoC 内部的 USB 主机控制器硬件,如 xHCI、EHCI、DWC3 等
  • 驱动位于:drivers/usb/host/
  • 注册为 usb_hcd,通过 usb_create_hcd() 初始化

2.2 USB 核心层(usbcore)

  • 负责:

    • 设备检测与枚举
    • 地址分配与端点配置
    • 设备树或 ACPI 的匹配注册
    • 驱动和设备匹配逻辑(VID/PID、Interface Class)
  • 核心文件:drivers/usb/core/

    • usb.c: 核心入口
    • hub.c: 管理 USB Hub 和设备热插拔
    • message.c: 控制传输的封装

2.3 类驱动(Class Drivers)

常见标准类驱动包括:

驱动模块说明
usb-storageU 盘、大容量存储设备
cdc-acmUSB 转串口设备,如 /dev/ttyACM0
uvcvideoUSB 摄像头
usbtmcUSB 测试与测量设备

2.4 驱动开发关键流程(主机端)

  1. 定义 struct usb_driver
  2. 填写 usb_device_id 匹配表
  3. 实现 probe()disconnect()
  4. 使用 usb_register_driver() 注册驱动
static struct usb_driver my_driver = {
  .name = "my_usb",
  .probe = my_probe,
  .disconnect = my_disconnect,
  .id_table = my_id_table,
};

三、设备模式(Gadget)驱动结构

3.1 USB Device Controller 驱动(UDC)

  • 位于:drivers/usb/gadget/udc/
  • 如:ci_hdrc, dwc2, musb
  • 通过 usb_add_gadget_udc() 注册控制器实例

3.2 USB Composite Framework

  • 用于构建复合 USB 设备(多功能设备)

  • 定义:

    • usb_composite_driver
    • usb_function
    • usb_configuration
  • 注册:usb_composite_probe()

3.3 功能驱动(Function Driver)示例

功能模块说明
g_serialUSB Gadget 串口设备(ttyGS0)
g_mass_storageUSB 模拟 U 盘设备
g_etherUSB 网络设备(usb0)
g_multi多功能复合设备

四、URB(USB Request Block)机制

4.1 URB 概念

URB 是内核中用于 USB 传输的核心结构,封装一次传输请求。

struct urb {
  void *transfer_buffer;
  int transfer_buffer_length;
  unsigned int pipe;
  struct usb_device *dev;
  void (*complete)(struct urb *urb);
};

4.2 使用流程(主机侧)

  1. 分配 URB:usb_alloc_urb()
  2. 填写缓冲区、方向、端点
  3. 提交 URB:usb_submit_urb()
  4. 回调处理:complete() 处理函数

五、设备识别与驱动绑定流程

5.1 枚举流程(主机侧)

  1. 主机通过 hub 检测到电平变化(上拉)
  2. 分配设备地址、读取设备描述符
  3. 主机根据 Interface Class 查找匹配驱动
  4. 调用驱动的 probe() 完成初始化

5.2 Gadget 框架启动流程(设备侧)

  1. usb_composite_register() 注册设备
  2. bind() 函数构建功能(如串口、存储)
  3. UDC 通知主机设备准备就绪

六、用户态接口与调试工具

6.1 用户态访问路径

  • /dev/ttyUSB0 / /dev/ttyACM0:串口类设备
  • /dev/sda1:USB 存储
  • /sys/class/usb_device/:内核状态节点

6.2 调试工具

命令用途
lsusb查看 USB 设备信息
usb-devices显示内核识别的设备结构
usbmonUSB 抓包日志调试(modprobe usbmon
strace跟踪 libusb 应用调用

七、主从模式差异总结

模块主机模式(Host)设备模式(Device)
控制器HCD(xHCI、EHCI)UDC(ci_hdrc、dwc2)
架构usb_driverusb_composite_driver
端点控制主机配置端点设备实现端点响应
功能驱动存储、摄像头、串口等g_mass_storage、g_ether、g_serial

八、USB 驱动开发常见陷阱与建议

  • 🚫 误用 Interface number:设备可能有多个接口,需要准确匹配 Interface
  • 🚫 未检查设备状态变化:断开重连等事件要及时处理
  • 使用 usbcore 提供的 API,避免直接读写控制器寄存器
  • 调试阶段使用 usbmon 分析传输细节

结语

USB 软件架构是 Linux 内核中最成熟、模块化程度最高的子系统之一。通过对 Host/Gadget 模式的结构分析、驱动开发流程讲解和 URB 通信机制的梳理,本文为理解和开发 USB 相关驱动打下坚实基础。掌握 USB 栈的使用与扩展,不仅能处理常见外设接入问题,更能开发出定制化的 USB 复合设备、传输接口或固件烧录工具。


支持作者,点击京东购买作者创作书籍《Yocto项目实战教程:高效定制嵌入式Linux系统》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值