从0到1构建USB应用:基于CherryUSB的STM32开发实例

【免费下载链接】CherryUSB CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP 【免费下载链接】CherryUSB 项目地址: https://gitcode.com/gh_mirrors/che/CherryUSB

CherryUSB是一款面向嵌入式系统的轻量级USB协议栈,支持设备端和主机端功能,能够帮助开发者快速实现各类USB应用。本文将以STM32系列芯片为例,详细介绍如何基于CherryUSB构建USB应用,从环境搭建到功能实现,让你轻松掌握嵌入式USB开发的核心技能。

CherryUSB简介:嵌入式USB开发的理想选择

CherryUSB采用分层架构设计,包含设备控制器驱动(DCD)、主机控制器驱动(HCD)、核心层和各类设备类驱动,支持多种USB IP核和操作系统抽象层。其模块化设计使得移植和扩展变得简单,非常适合资源受限的嵌入式系统。

CherryUSB架构图 CherryUSB架构图:展示了从硬件层到应用层的完整协议栈结构,支持设备端和主机端双重功能

主要特点包括:

  • 支持USB 2.0全速/高速模式
  • 丰富的设备类支持:CDC、HID、MSC、Audio、Video等
  • 适配多种MCU平台和操作系统
  • 占用资源少,代码精简高效

开发环境准备:STM32基础配置

硬件与工具准备

开始前需要准备:

  • STM32开发板(推荐F4/H7系列,如STM32F429IGT6)
  • STM32CubeMX配置工具
  • Keil MDK或STM32CubeIDE开发环境
  • USB数据线和调试器

获取CherryUSB源码

通过以下命令克隆CherryUSB仓库:

git clone https://gitcode.com/gh_mirrors/che/CherryUSB

STM32CubeMX基础配置

  1. 打开STM32CubeMX,创建新项目并选择对应芯片型号
  2. 配置系统时钟(RCC),推荐使用外部晶振
  3. 配置调试接口(SWD)和UART(用于日志输出)

STM32CubeMX时钟配置 STM32CubeMX时钟配置界面:正确配置HSE和系统时钟是USB正常工作的基础

  1. 配置USB外设:
    • 对于FSDEV IP(如F1系列):勾选USB外设
    • 对于DWC2 IP(如F4/H7系列):勾选USB_OTG_FS或USB_OTG_HS
  2. 确保USB时钟配置为48MHz(USB工作的必要条件)

快速上手:CDC串口通信实例

CDC(通信设备类)是最常用的USB应用之一,可将嵌入式设备模拟为虚拟串口。下面以CDC_ACM模板为例,实现一个简单的USB串口通信功能。

移植CherryUSB到STM32

  1. 添加必要源码文件到工程:

    • 核心文件:core/usbd_core.c
    • 控制器驱动:根据芯片选择port/dwc2/usb_dc_dwc2.cport/fsdev/usb_dc_fsdev.c
    • CDC类驱动:class/cdc/usbd_cdc.c
    • 模板代码:demo/cdc_acm_template.c
  2. 创建配置文件:复制cherryusb_config_template.h到工程目录,重命名为usb_config.h,并根据硬件配置端点数量和FIFO大小。

  3. 实现底层初始化:在usb_dc_low_level_init函数中配置GPIO和时钟:

USB底层初始化代码 USB底层初始化代码:配置USB相关GPIO、时钟和中断

CDC功能实现

CDC模板代码位于demo/cdc_acm_template.c,主要包含以下部分:

  1. 描述符定义:包含设备描述符、配置描述符和字符串描述符
  2. 端点配置:定义IN/OUT端点地址和中断端点
  3. 事件处理:实现USB连接、配置等事件的处理函数
  4. 数据收发:实现CDC数据的接收和发送功能

关键初始化代码:

void cdc_acm_init(uint8_t busid, uint32_t reg_base)
{
    usbd_desc_register(busid, cdc_descriptor);
    usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
    usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
    usbd_add_endpoint(busid, &cdc_out_ep);
    usbd_add_endpoint(busid, &cdc_in_ep);
    usbd_initialize(busid, reg_base, usbd_event_handler);
}

编译与测试

  1. 编译工程并下载到开发板
  2. 使用USB线连接开发板到PC
  3. 安装虚拟串口驱动(如需要)
  4. 打开串口助手,选择对应的虚拟串口
  5. 发送数据,开发板将返回接收到的数据

USB枚举过程解析

USB设备接入主机后,会经历枚举过程,主机通过一系列控制传输获取设备信息并完成配置。CherryUSB已内置完整的枚举处理逻辑,用户无需深入了解枚举细节。

USB枚举过程 USB枚举过程抓包:展示了从设备连接到配置完成的完整交互过程

枚举主要步骤:

  1. 设备连接,主机检测到电平变化
  2. 主机复位设备
  3. 主机获取设备描述符
  4. 主机设置设备地址
  5. 主机获取配置描述符
  6. 主机设置设备配置
  7. 枚举完成,设备进入配置状态

高级应用:扩展更多USB功能

CherryUSB提供了丰富的设备类支持,除了CDC,还可以轻松实现其他USB功能:

HID设备(鼠标/键盘)

使用demo/hid_keyboard_template.cdemo/hid_mouse_template.c模板,可快速实现HID设备功能。只需修改报告描述符和数据发送逻辑,即可模拟键盘或鼠标操作。

大容量存储设备(MSC)

通过demo/msc_storage_template.c模板,可将开发板模拟为U盘设备。需要实现存储介质的读写接口,支持SD卡或内部Flash等存储设备。

复合设备

CherryUSB支持复合设备功能,可同时实现多种USB设备类。例如demo/cdc_acm_hid_msc_template.c展示了如何同时实现CDC、HID和MSC功能。

调试与问题排查

USB开发过程中可能会遇到各种问题,以下是一些常用的调试方法:

  1. 查看日志输出:确保UART日志功能正常,CherryUSB会输出关键调试信息
  2. USB抓包分析:使用Wireshark配合USB抓包工具(如USBPcap)分析USB通信过程
  3. 检查硬件连接:确保USB差分线(D+、D-)连接正确,阻抗匹配
  4. 确认时钟配置:USB模块必须工作在48MHz时钟下
  5. 检查端点配置:确保端点地址和类型配置正确

总结与进阶

通过本文的介绍,你已经了解了如何基于CherryUSB在STM32上实现USB应用。从环境搭建到功能实现,CherryUSB提供了简洁而强大的API,大大降低了嵌入式USB开发的门槛。

官方文档位于docs/source/index.rst,包含更详细的API说明和移植指南。你可以继续探索CherryUSB的高级功能,如USB主机模式、音频设备、视频设备等,实现更复杂的USB应用。

希望本文能帮助你快速上手嵌入式USB开发,如有任何问题,欢迎参与CherryUSB项目的讨论和贡献!

【免费下载链接】CherryUSB CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP 【免费下载链接】CherryUSB 项目地址: https://gitcode.com/gh_mirrors/che/CherryUSB

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐