关于USB的一些知识汇总
在嵌入式与物联网设备开发中USB 不只是一个接口而是一整套复杂的通信体系。本文在基础 USB 认知Host / Device / OTG / 接口类型之上进一步补充 USB 协议分层结构协议栈 Linux USB 驱动架构⚙️ 工程落地理解方式 一、USB 的核心角色回顾Host主机控制通信、供电、发起请求Device设备被动响应请求OTG支持角色切换Host / Device 本质USB 是主从架构不是对等通信 二、USB 协议分层结构协议栈模型USB 并不是“一根线直接通信”而是一个完整的分层协议体系。 1️⃣ USB 协议栈总体结构┌────────────────────────────┐ │ Application │ 应用层如 U盘 / 摄像头 / 串口 ├────────────────────────────┤ │ Class Driver │ 类驱动HID / Mass Storage / CDC ├────────────────────────────┤ │ USB Core │ USB核心层Linux usbcore ├────────────────────────────┤ │ Host Controller │ HCDxHCI / EHCI / OHCI ├────────────────────────────┤ │ USB Bus │ USB总线层 ├────────────────────────────┤ │ PHY Layer │ 物理层D/D- / Type-C CC └────────────────────────────┘ 每一层的作用 ① 应用层Application用户直接看到的功能U盘挂载USB摄像头USB转串口 ② Class Driver类驱动USB 最大特点之一“按类别驱动”常见类Class作用HID键盘 / 鼠标MSCU盘 / 存储设备CDCUSB转串口UVC摄像头 关键点USB 不是按厂商驱动而是按“类别驱动” ③ USB Core核心层Linux 内核中的usbcore设备枚举设备管理接口匹配驱动绑定⚙️ ④ Host Controller DriverHCD控制 USB 控制器硬件控制器说明EHCIUSB2.0 高速OHCI/UHCIUSB1.1xHCIUSB3.x / USB-C 这一层直接操作硬件寄存器 ⑤ PHY Layer物理层真实信号层D / D- 差分信号USB 5V 电源Type-C CC 引脚角色识别 三、Linux USB 驱动架构重点工程部分USB 在 Linux 中是一个典型分层驱动模型。 1️⃣ Linux USB 架构图User Space ↑ /dev/ttyUSB0 ↑ ┌───────────────────┐ │ USB Class Driver │ ← cdc_acm / usb-storage / usbhid └───────────────────┘ ↑ ┌───────────────────┐ │ usbcore │ ← USB核心层 └───────────────────┘ ↑ ┌───────────────────┐ │ Host Controller │ ← xHCI driver └───────────────────┘ ↑ USB PHY ↑ USB Device⚙️ 2️⃣ USB 驱动匹配机制关键Linux USB 驱动不是“插上就随便跑”而是 通过 VID / PID 匹配USB_DEVICE(0x12D1, 0x1001)VID 厂商 IDPID 产品 ID 通过 Class 匹配例如CDC串口HID键鼠MSCU盘 这也是“免驱设备”的来源 3️⃣ /dev/ttyUSB0 是怎么来的以 USB 转串口为例USB设备 ↓ usbcore识别 ↓ cdc_acm / usbserial driver ↓ tty layer ↓ /dev/ttyUSB0⚠️ 常见问题解释❗ 为什么 ttyUSB0 会变因为USB 枚举顺序变化多设备插拔顺序变化udev 没有固定规则 解决方案✔ 使用 udev rule 固定设备SUBSYSTEMtty, ATTRS{idVendor}xxxx, SYMLINKusb_serial✔ 或使用/dev/serial/by-id/ 四、OTG 与 Linux 的关系OTG 实际上就是“同一个 USB 控制器切换 Host / Device 模式”Linux 中体现为模式内核角色HostxHCI/EHCI driverDevicegadget driver Device 模式GadgetLinux 可以模拟 USB 设备USB 网卡USB 串口USB 存储 使用gadget framework OTG Linux结构图建议建议画一张综合图Linux Device ┌───────────────┐ │ Host Mode │ │ Gadget Mode │ └──────┬────────┘ OTG │ USB PHY Controller │ USB Port⚡ 五、工程总结USB 可以抽象成三句话 1️⃣ 架构本质USB Host 控制 Device 响应 2️⃣ 软件本质USB Class Driver Core HCD 3️⃣ Linux本质USB 可热插拔 自动匹配驱动 分层架构六、“免驱”≠一定能用USB设备为什么插上还是没驱动在实际开发和现场运维中经常会遇到一个典型误区❌ “官方说免驱但插上设备就是没有驱动/没有节点”这里的关键是免驱指的是系统自带 Class Driver而不是保证一定可用。 1️⃣ “免驱”的真实含义USB所谓“免驱”本质是操作系统已经内置了对应Class Driver类驱动例如HID键盘/鼠标MSCU盘CDC串口UVC摄像头 只要设备符合标准 Class就能自动绑定驱动。❗ 2️⃣ 为什么“免驱设备”仍然可能不工作可以归为三类问题 1硬件层USB都没真正识别现象lsusb 无设备变化原因线材只有充电无数据OTG未开启 / 未供电USB Host模式未生效 本质设备根本没进入枚举阶段 2枚举成功但Class不匹配现象lsusb 能看到设备但没有 /dev/xxx原因设备使用 Vendor Specific Class0xFFVID/PID 不在驱动匹配表Descriptor 不符合标准 CDC/HID/MSC 本质系统不知道用哪个驱动⚙️ 3驱动存在但未加载/未绑定现象lsusb 有设备但没有 ttyUSB / video / block 节点原因modprobe cdc_acm modprobe usbserial或内核未编译相关模块驱动未自动 probe 本质驱动在但没“认出你”如果在映翰通的设备上明明是免驱的设备却仍旧无法正常工作可以提供 pidvid 驱动文件预置到系统内解决问题。