USB 学习指南+软硬件框架

目录

  • 一、前言
  • [二、为什么项目需要 USB](#二、为什么项目需要 USB)
  • [三、USB 软件框架:总线驱动 + 设备驱动](#三、USB 软件框架:总线驱动 + 设备驱动)
  • [四、USB 硬件框架:Host-Controller-Hub-Device](#四、USB 硬件框架:Host-Controller-Hub-Device)
  • [五、USB 设备识别三阶段](#五、USB 设备识别三阶段)
  • [六、四引脚 + 上拉电阻:电平检测原理](#六、四引脚 + 上拉电阻:电平检测原理)
  • [七、USBX:Azure RTOS 的 USB 协议栈](#七、USBX:Azure RTOS 的 USB 协议栈)
  • 八、学习路线图
  • 九、常见坑
  • 十、结尾

一、前言

大家好,这里是 Hello_Embed

前几篇我们把 UART 做到了极致------DMA+IDLE + OOP 封装 + libmodbus 移植。但开发板的 UART2/UART4 是 RS-485/232 封装的,它们之间可以互通,却无法直连 PC。PC 和开发板的通信靠的是 USB

本篇开始 USB 学习路线:从软硬件框架到 USBX 移植 CDC-ACM,最终让 PC 通过 USB 虚拟串口访问 STM32 上的 libmodbus 从机。


二、为什么项目需要 USB

UART USB
速度 ≤ 2Mbps 12Mbps(全速) / 480Mbps(高速)
多设备 一对一 一主机拖 127 设备
驱动 无标准枚举 自动枚举 + 描述符匹配驱动
本项目角色 中控↔传感器 (RS-485) PC↔中控 (USB CDC)

本项目 USB 的具体用途:STM32H5 通过 USB CDC-ACM(虚拟串口)模拟一个串口设备,PC 端看到的就是一个 COM 口,ModbusPoll 直接当串口用------上层 API 不变,物理层从 UART2 换成了 USB。


三、USB 软件框架:总线驱动 + 设备驱动

复制代码
┌─────────────────────────────────┐
│  PC 应用程序(ModbusPoll)       │
├─────────────────────────────────┤
│  USB 设备驱动程序(CDC-ACM)     │  ← Windows 自动匹配
├─────────────────────────────────┤
│  USB 总线驱动程序(USB Bus)     │  ← Windows 内置
├─────────────────────────────────┤
│  USB Host 控制器                │  ← 硬件
└───────────┬─────────────────────┘
            │ D+/D-
┌───────────▼─────────────────────┐
│  STM32H5 USB Device 控制器      │  ← 硬件
├─────────────────────────────────┤
│  USBX 协议栈(STM32 端)        │  ← Azure RTOS
├─────────────────────────────────┤
│  应用程序(libmodbus 从机)      │
└─────────────────────────────────┘

两层关键:

  1. USB 总线驱动(Windows 内置)------负责识别设备、分配地址
  2. USB 设备驱动(CDC-ACM 驱动)------负责具体通信协议(虚拟串口就用 usbser.sys)

STM32 端对应的软件是 USBX(Azure RTOS 的 USB 协议栈),它实现 Device 端的 USB 协议,向 PC 报告"我是一个 CDC-ACM 串口设备"。


四、USB 硬件框架:Host-Controller-Hub-Device

复制代码
PC CPU
  └─ USB Host 控制器(内置 Root Hub)
       ├─ Hub(扩展端口, 最多 6 级)
       │   ├─ Device A
       │   └─ Device B
       └─ Device C(直接连接)
  • Host 控制器:发起所有通信,设备被动响应
  • Root Hub:集成在 Host 控制器内部,提供物理端口
  • Hub:USB 分线器,最多级联 6 级
  • Device:被连接的设备(我们的 STM32 就是 Device)

五、USB 设备识别三阶段

USB 设备从插入到可用,经历三个阶段:

1. 物理检测:D+/D- 电平变化。Host 检测到 Device 插入。

2. 枚举(Enumeration)

复制代码
Host ──获取设备描述符──→ Device  ← "我是谁"
Host ──分配地址(1~127)─→ Device  ← "你的编号是 X"
Host ──获取配置描述符──→ Device  ← "你有哪些功能"
Host ──加载驱动────────→         ← "匹配 CDC-ACM 驱动"

3. 正常通信:驱动加载完成,应用程序可以打开 COM 口通信。

关键是描述符------Device 向 Host 报告自己的身份信息(设备类型、厂商标识、接口类型等)。STM32 端用 USBX 配置这些描述符,告诉 PC"我是 CDC-ACM 串口设备"。


六、四引脚 + 上拉电阻:电平检测原理

USB 接口 4 根引脚:

引脚 作用
VBUS (5V) 供电
GND
D+ 数据正
D- 数据负

设备速度识别靠上拉电阻

  • D+ 接上拉(1.5kΩ 到 3.3V)→ 全速设备(12Mbps)
  • D- 接上拉 → 低速设备(1.5Mbps)

STM32H5 的 USB 外设内部已集成上拉电阻,CubeMX 配置时勾选即可。


七、USBX:Azure RTOS 的 USB 协议栈

STM32H5 不裸写 USB 协议,而是用 Azure USBX(ThreadX 生态的一部分,已适配 FreeRTOS)。

USBX 在本项目的角色:

复制代码
应用程序(ModbusServerTask)
  └─ 通过 UART_Device 接口操作
       └─ g_usbserial_dev(USB CDC 的 OOP 封装)
            └─ USBX CDC-ACM 中间件
                 └─ USBX Device Stack
                      └─ STM32H5 USB OTG HAL 驱动

USBX 帮我们做好的事:

  • 解析 USB 标准请求(GET_DESCRIPTOR、SET_ADDRESS 等)
  • 管理端点(Endpoint)的数据传输
  • CDC-ACM 的类协议封装(虚拟串口的线路编码、状态通知)

我们只需要:

  • CubeMX 配置 USB OTG 外设 + USBX 中间件
  • 稍作源码改造(适配 FreeRTOS 内存管理)
  • OOP 封装一个 g_usbserial_dev

八、学习路线图

复制代码
Note 16: USB 框架 ← 本篇(为什么用 USB + 软硬件架构)
Note 17: USB 协议层(包格式、传输类型、描述符详解)
Note 18: 移植 USBX + CDC-ACM(CubeMX 配置 + 源码改造 + 上机)
Note 19: USB CDC OOP 封装(g_usbserial_dev + ModbusPoll 联调)

4 篇搞定 USB,之后 Note 20 开始 libmodbus 上机实验(USB 后端)。


九、常见坑

ST-Link 是调试器,它自带的虚拟串口走的是 ST-Link 自己的 USB。我们学的是 STM32H5 芯片本身的 USB 外设------用 PA11(D-)/PA12(D+) 引脚。

9.2 USB 和 UART 的"串口"不是一回事

USB CDC-ACM 是模拟串口------PC 端看到的 COM 口,底层走的其实是 USB 包,不是 UART 电平。中间有 USBX + CDC 协议栈做转换。

9.3 CubeMX 配置 USBX 需要 ThreadX 内核(可选)

USBX 原生依赖 ThreadX,但 ST 提供了 FreeRTOS 适配层(ux_stm32_config.h),不需要额外安装 ThreadX。


十、结尾

本篇建立了 USB 的系统框架认知:Host/Device 架构、枚举三阶段、USBX 协议栈的角色。下一篇深入 USB 协议层------包格式、四种传输类型、描述符树,把"设备如何向 Host 描述自己"讲透。

相关推荐
和平宇宙19 分钟前
AI笔记005. hermes-DeepSeek V4 Pro, 128K上下文引发的探索
前端·人工智能·笔记
换个昵称都难1 小时前
webrtc 音频模块FEC模块
网络·音视频·webrtc
十月的皮皮1 小时前
C语言学习笔记20260606- 求月份天数三种写法
c语言·笔记·学习
cmes_love1 小时前
Level 2逐笔成交历史数据下载方法笔记
数据库·笔记·oracle
youngerwang1 小时前
【从搬运工到协处理器:网卡芯片架构、算法、验证与边缘演进深度剖析】
网络·算法·架构·芯片
程序员黑豆2 小时前
AI全栈开发之Java:怎么配置Java环境变量
前端·后端·ai编程
Cloud_Shy6182 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法
蓝晶之心2 小时前
cursor初学实战项目——待办清单
ai编程
kebidaixu2 小时前
FreeRTOS 移植到 STM32F407VETX 记录(一)
stm32·单片机·嵌入式硬件
问心无愧05132 小时前
ctf show web入门110
前端·笔记