news 2026/6/23 10:39:14

[STM32F1] 【每周分享】以stm32f103为例谈谈tinyusb的性能测试与优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[STM32F1] 【每周分享】以stm32f103为例谈谈tinyusb的性能测试与优化

tinyusb是一款MIT协议开源的跨平台USB host/device协议栈,专为嵌入式系统设计,各种常见的usb class都有实现,常见的或不常见的usb ip都有支持,比如像dwc2、musb、chipidea、stm32 fsdev等。更为友好的是它自带了大量的测试样例,也自带了各种常见MCU开发板的移植。当下支持usb device的MCU很常见,所以tinyusb在这些MCU上应用很广泛,由此一个常见的话题是如何评价目标MCU tinyusb的性能,在获得性能数据后如何提升性能。

一个比较好的测试场景是usb cdc loopback设备,所谓loopback就是把收到的数据再发回去,然后上位机通过c或者python写的程序与下位机的cdc交互,测量读写一大块数据的时间从而获得性能数据。此方法优点是:usb cdc设备可通用操作系统usb cdc驱动,所以我们不用再实现上位机操作系统下的驱动;另usb cdc是bulk传输,在usb设备无其他端点时,可以简单认为测得的cdc性能数据即MCU的usb性能数据。

测试用例usb cdc loopback的实现
如上所述,tinyusb自带大量的测试样例,我们通常不会从头开始写,而是基于测试样例改。tinyusb在examples/device/cdc_dual_ports/有一个双cdc端口的实现例子,原来的实现是把usb cdc端口收到的数据写到uart中去,为实现测试性能的usb cdc loopback, 笔者将其中的cdc_task函数修改如下:

复制
  1. staticvoidcdc_task(void) {
  2. for(uint8_titf =0; itf < CFG_TUD_CDC; itf++) {
  3. // connected() check for DTR bit
  4. // Most but not all terminal client set this when making connection
  5. // if ( tud_cdc_n_connected(itf) )
  6. {
  7. if(tud_cdc_n_available(itf)) {
  8. uint8_tbuf[64];
  9. uint32_tcount = tud_cdc_n_read(itf, buf,sizeof(buf));
  10. // echo back
  11. tud_cdc_n_write(itf, buf, count);
  12. }
  13. }
  14. }
  15. }




目标MCU和开发板
笔者选中基于STM32F103C8T6的小蓝板,板子非常流行且价格便宜,tinyusb也有现成的移植,hw/bsp/stm32f1/boards/stm32f103_bluepill

编译小蓝板固件和烧录

复制
  1. cdexamples/device/cdc_dual_ports
  2. makeBOARD=stm32f103_bluepill


编译出的固件在_build/stm32f103_bluepill/cdc_dual_ports.bin,将其烧录到小蓝板即可,比如笔者使用openocd烧录

复制
  1. openocd-f interface/stlink.cfg -f target/stm32f1x.cfg -c"program _build/stm32f103_bluepill/cdc_dual_ports.bin verify reset exit 0x8000000"

openocd烧录固件的截图:



烧录完毕后板子自动重启,用usb线缆连接PC机与板子usb口,PC linux dmesg信息如下:



可以看到基于tinyusb的cdc acm设备已经被PC识别,接下来需要来个性能测试的上位机,为简单起见,直接python脚本吧。

上位机测试python程序
笔者使用的python程序代码如下:

复制
  1. #!/usr/bin/python3
  2. importsys
  3. importserial
  4. fromtimeimportperf_counter
  5. defformat_bytes(size):
  6. B = float(size)
  7. KB = float(1024)
  8. MB = float(KB **2)# 1,048,576
  9. ifB < KB:
  10. return'{0} {1}'.format(B,'B')
  11. elifKB <= B < MB:
  12. return'{0:.2f} KB'.format(B/KB)
  13. else:
  14. return'{0:.2f} MB'.format(B/MB)
  15. defmain():
  16. iflen(sys.argv) !=2:
  17. print("No port name specified")
  18. exit()
  19. ser = serial.Serial(sys.argv[1], baudrate=115200)
  20. data = bytes()
  21. foriinrange(4096):
  22. data = data + bytes(range(256))
  23. print("Testing port", sys.argv[1])
  24. t_start = perf_counter()
  25. ser.write(data)
  26. t_stop = perf_counter()
  27. print("Throughput:", format_bytes(4096*256/ (t_stop - t_start)) +"/s")
  28. if__name__ =="__main__":
  29. main()


测得的性能数据:




性能数据分析
这个数据可以算比较差的。STM32F103的usb特征是full speed usb device,理论速率12Mbps,考虑到协议负载等,理论上的传输性能大概在1MB/s上下。

性能优化措施
据笔者对于tinyusb源码分析发现tinyusb默认设置是比较保守的,追求资源占用最少。例如:默认编译
优化选项是”-Os“而非常见的"-O2"或"-O3", 且各buf size也是设置最小的。笔者在STM32F103平台采取
性能优化措施如下:

去掉cdc dual port中的一个
笔者只用一个cdc port,故而删除dual port中一个,以节省资源

编译”-Os“改成”-O2“

复制
  1. diff --git a/examples/build_system/make/toolchain/gcc_common.mk b/examples/build_system/make/toolchain/gcc_common.mk
  2. index42fd01183..9364177a0100644
  3. --- a/examples/build_system/make/toolchain/gcc_common.mk
  4. +++ b/examples/build_system/make/toolchain/gcc_common.mk
  5. @@ -39,7+39,7@@ CFLAGS_CLANG += \
  6. # -Wconversion
  7. # Size Optimization as default
  8. -CFLAGS_OPTIMIZED ?= -Os
  9. +CFLAGS_OPTIMIZED ?= -O2
  10. # Debugging/Optimization
  11. ifeq ($(DEBUG),1)



增大CFG_TUD_CDC_EP_BUFSIZE与CFG_TUD_CDC_RX/TX_BUFSIZE

复制
  1. --- a/examples/device/cdc_dual_ports/src/tusb_config.h
  2. +++ b/examples/device/cdc_dual_ports/src/tusb_config.h
  3. @@-91,7+91,7@@
  4. #endif
  5. //------------- CLASS -------------//
  6. -#define CFG_TUD_CDC 2
  7. +#define CFG_TUD_CDC 1
  8. #define CFG_TUD_MSC 0
  9. #define CFG_TUD_HID 0
  10. #define CFG_TUD_MIDI 0
  11. @@-100,11+100,11@@
  12. #define CFG_TUD_CDC_NOTIFY 1// Enable use of notification endpoint
  13. // CDC FIFO size of TX and RX
  14. -#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
  15. -#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
  16. +#define CFG_TUD_CDC_RX_BUFSIZE 4096
  17. +#define CFG_TUD_CDC_TX_BUFSIZE 4096
  18. // CDC Endpoint transfer buffer size, more is faster
  19. -#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
  20. +#define CFG_TUD_CDC_EP_BUFSIZE 4096




再次编译烧录后性能测试如下



可以看到经笔者优化后,usb cdc基本达到期望的性能。


---------------------
作者:xhackerustc
链接:https://bbs.21ic.com/icview-3502794-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 10:37:13

SH9同源异质视角下镜像生命的演化逻辑与未来命运——基于达尔文进化论的未来学深度研究报告(世毫九实验室原创研究)

SH9同源异质视角下镜像生命的演化逻辑与未来命运——基于达尔文进化论的未来学深度研究报告&#xff08;世毫九实验室原创研究&#xff09; 作者&#xff1a;方见华 单位&#xff1a;世毫九实验室 核心观点摘要 本报告以同源异质为核心进化视角——即生命可起源于相同物质基础但…

作者头像 李华
网站建设 2026/6/23 10:36:32

做好引用优化,你的AI引用率可以提升3.2倍!

概述你有没有发现&#xff0c;同样做内容&#xff0c;有些网站总是被ChatGPT、Perplexity频繁引用&#xff0c;而你的内容写得也不差&#xff0c;却从来没被AI"点名"过&#xff1f;这不是运气问题&#xff0c;而是引用优化&#xff08;Citation Optimization&#xf…

作者头像 李华
网站建设 2026/6/23 10:33:58

基于FISCO BCOS联盟链构建匿名评卷与隐私保护的考试系统

1. 项目概述&#xff1a;当传统考试遇上区块链每次看到关于考试公平性的讨论&#xff0c;我总会想起几年前参与的一个项目评审。当时&#xff0c;一个大型职业资格认证机构正被“评卷过程不透明”、“成绩被篡改疑云”等舆论困扰。他们尝试了各种技术手段&#xff0c;从数据库加…

作者头像 李华
网站建设 2026/6/23 10:33:21

Django毕设选题推荐:基于 Django 的人脸核验式自习室座位管理系统设计与开发 智慧校园背景下自习室人脸识别预约系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/23 10:32:38

网络变压器(网变)到底有哪些认证?一文讲清,别再混了

网络变压器&#xff08;网变&#xff09;到底有哪些认证&#xff1f;一文讲清&#xff0c;别再混了做以太网硬件选型时&#xff0c;规格书上 UL、RoHS、IEEE 802.3、AEC-Q200 一堆字母经常被当成同一回事。其实它们根本不是一类东西。这篇用最短的篇幅&#xff0c;把网变相关的…

作者头像 李华