STM32H5上TinyUSB移植与高效USB控制实现指南
基于stm32h5进行tinyusb移植
,使用的tinyusb的目的是想快速的使用usb的相关的功能,同时可以兼容多个芯片平台。
在现有的裸机工程中加入tinyusb功能,实现cdc例程功能,实现usb虚拟串口,同时将收到的数据发送返回
详细步骤
1. 获取tinyusb源码
hathach/tinyusb: An open source cross-platform USB stack for embedded system (github.com)
通过下载或git clone的方式都可以。具体已支持的平台可以在Readme查看
2. tinyusb源码介绍

只用到以下这3部分内容,其他的在该移植方案中用不到
examples 例程函数,针对功能进行参考使用
hw 硬件驱动适配层,有部分硬件处理需要用到
src tinyusb源码,需要包含在工程中,并在功能按需加入
3. 在stm32工程中加入源码
此部分建议按照个人工程风格处理,介绍具体调整的内容和移植
新建文件夹 tinyusb,并创建2个子文件夹,分别为bsp和user,其中src为原tinyusb库直接拷贝过来,如下图所示

bsp用于适配不用的硬件调整
1)拷贝源码 hw\bsp\下的 board.c 和 board_api.h 到bsp目录下
2)拷贝源码 hw\bsp\stm32h5\下的 family.c 到bsp目录下
3)拷贝源码 hw\bsp\stm32h5\boards\stm32h563nucleo\ 下的 board.h 到bsp目录下
此文件可以不要的,但是该文件中有关于时钟初始化的内容,可以在原工程加入此时钟的调整,按需处理
修改操作
实际上这部分的内容用的不多,如果本身驱动已经正常的情况下,可以不使用。但是为了兼容例程中的部分接口,所以保留,但进行一下调整。
更好的方式可以单独做一个文件,并将需要的接口统一在一个文件上即可,当前为了快速验证,不做调整
1. family.c 仅保留以下接口,其他的删除或屏蔽即可

2. boardInit接口保留并调整



此部分内容可能与原工程有冲突,建议按需处理。本测试是基础工程来添加移植的,所以保留此部分,屏蔽原工程的 SysTick_Handler()

3. board.c 仅保留以下接口,其他删除或屏蔽均可。需要确保原来的工程可以进行printf打印,否则可能无法打印调试等功能。按需处理


4. board.h 内容全部屏蔽或删除本文件,拷贝此部分内容到原工程的时钟初始化中,实现USB时钟的分频配置,否则USB功能异常

5. board_api.h 该文件内容主要是一些接口声明,方便其他相关的函数调用。因为基础工程已有串口打印等功能,所以仅保留mcuid和systick部分内容


没有使用rtos,裸机逻辑


user为具体的usb应用逻辑,这里使用的cdc模式进行测试,所以用的是cdc_msc例程
1)拷贝源码 examples\device\cdc_msc\src\ 下的内容到user目录下
2)因为仅测试cdc的功能,删除msc_disk.c 文件
3)将main文件名修改为 cdcApp.c 名字按个人风格定义
4)修改 tusb_config.h 文件内容,因为仅用到cdc功能,针对性机型配置修改
增加使用的mcu型号,明确定义mcu平

打开日志调试,担心首次移植可能有异常,通过日志判断

仅使用cdc测试,关闭msc的类别使能

屏蔽msc的buff定义
![]()
5)修改 usb_descriptors.c 文件内容,仅使用cdc进行调整,加深对tinyusb的类别设置的理解
头文件调整,因为没有再次分层处理了,所以直接引用即可
![]()
屏蔽或删除MSC部分内容

去掉msc部分的长度,否则描述符有异常,usb无法识别出来



6)修改 cdcApp.c 文件内容,仅使用cdc功能,屏蔽闪灯等内容操作,也可保留。但是因为我们仅测试usb cdc的功能,减少代码干扰
调整头文件
![]()
调整 main() 函数命名为usbcdcInit(),避免影响到原工程的main函数

屏蔽或删除不相关的内容
![]()
因实际测试也只测试该usb功能,所以while(1)循环执行也没关系。实际应用时,需要按需调整

屏蔽闪灯部分,并更换了打印,便于调试判断

屏蔽闪灯的相关操作

4. 基于cdc应用调整keil的工程配置
将tinyusb文件夹加入到现有的工程中,按需处理。同时在keil中配置相关的内容。因为仅做为usb的device栈使用,所以不需要添加host相关的代码,具体工程添加内容如下,自行对应添加

头文件添加如下,自行对应添加

同时在main函数中,加入usb应用的相关代码,并进行编译

添加完相关的代码后进行编译,可能会存在适配硬件的 dcd_stm32_fsdev.c 源码报错:

仅需要在 asm("NOP"); 前加2下划线 __asm("NOP"); 即可,这个是c代码规则问题。重新编译通过

烧录到硬件上运行,并接上usb接口到PC上,查看设备管理,可以看到一个虚拟的串口设备,则tinyusb的移植完成,实现cdc虚拟串口功能

实现数据接收和发送,返回一样的内容

5. 资源对比
1)未添加前tinyusb功能前的原始工程资源使用情况如下:
flash=18860+668+16=19544B≈19KB
ram=16+2000=2016B≈2KB

2)添加tinyusb的cdc功能后的工程资源使用情况如下:
flash=36608+2080+60=38748B≈38KB
ram=60+3092=3152B≈3.1KB

3)对比分析得出,tinyusb usb设备协议栈使用cdc功能,flash需要20KB左右的空间,ram需要1KB左右
附录
有工程代码需求的请联系哈~~
作者:pergon