运行 Ux_Host_HUB_HID_MSC 通过 Hub 连接 U 盘读写不稳定问题分析 LAT1511

***关键字:*USB_OTG_HS,USB,HUB,FILEx,U 盘

1. 前言

客户使用 STM32U5 来开发一款外销型充电产品时,需要使用到 USB_OTG_HS 实现 HUB功能,并对 HUB 上的 U 盘进行高速写入操作。然而,客户在 NUCLEO-U5A5ZJ 板上运行 ST 官方例程 Ux_Host_HUB_HID_MSC 进行 U 盘性能读写测试时发现,在向 U 盘中写入小量数据是好的。但是,如果一次性连续写入大量数据如 1G 时会随机出现写入失败,返回值为 0x5C。

客户进一步反馈,如果直接将 U 盘连接到 NUCLEO 板,不通过 HUB 转接是 OK 的。且对U 盘有选择性,有些 U 盘出错概率小一些,有些概率 100%出现。希望知道 STM32U5 的 U 盘最快读写速度是多少。

2. 问题调研与复现

对客户板子及原理图进行检查后并未发现明显问题,笔者使用 STM32U5A9J-DK 板子对问题进行了验证。由于 FILEx 默认只支持 FAT32 格式的 U 盘,笔者使用的 U 盘容量是64G,需使能对 ExFAT 格式大容量 U 盘支持。

例程默认的 U 盘写入测试程序如下图所示:

显然例程默认数据单次写入长度是很小的,而且只写入了一次,频次远远不够。

修改测试程序大幅提高单次数据写入长度和数据吞吐量,测试代码如下所示。

笔者一共测试了 3 个不同品牌型号的 U 盘,测试结果如下:

所有 U 盘直连到板子都能成功写入,但是当通过 HUB 连接后,U 盘均会出现写入失败,只是各品牌的 U 盘出失败的概率不一样,还与 Hub 的口相关,有些 PORT 口概率低一些。

如下图所示:

将 UCHAR Write_buffer64单次写入数据长度改为 64/128/256/512 进行测试发现,可以成功(但是偶尔也会出错),但是速率无法接受。

3. 问题解决办法

通过上面对问题的复现,U 盘写入失败确实与 Hub 有关,通过对 FILEx 写入函数 fx_file_write 进行 debug,发现返回值 0x5C 并不属于 FILEx 模块里面定义的返回值,而是在 USBx/core 的头文件中定义的,0x5C 为 USB 传输请求超时。

进一步跟踪代码发现,出现传输超时由_ux_hcd_stm32_request_control_transfer 函数内部等待信号量时发生超时:

经过多次反复尝试,修改单次写入长度 Length 的大小(Write_bufferLength)可以显著改善。因此,笔者大胆推测接 HUB 后,引发的 Timeout 原因极有可能与 MCU 处理性能密切相关,笔者查阅了 HUB 的相关资料,市面上大部分 HUB 主控芯片均采用高性能 ASIC 专用芯片,往往HUB 具有较高的数据吞吐量, 极低的响应延时时间。

既然,推测可能是与 MCU 处理性能相关,那么我们有没有什么办法提高 MCU 处理性能呢?经过检查代码发现在初始化 USB_OTG_HS 时内部 DMA 是没有使能的。于是使能USB_OTG_HS 内部专用 DMA。

重新编译后,再次下载运行,插上 HUB 重新测试写入超时现象消失,笔者分别将单次写入长度最大设置到 64K,即 Write_buffer64\*1024,并且交叉更换不同的 HUB 和 U 盘写入仍然正常。

如下图所示:

使能 USB_OTG_HS 的 DMA 本质是减小了 CPU 的负载,从而提升总线响应时间和效率。既然使能 DMA 可以解决此问题。这又令笔者想到了 STM32H5 的 ICache 支持 2 种配置模式,分别为 :

1-way(direct mapped mode) :每个缓存块只能存储在缓存中的一个固定位置。每个块只能存放在特定位置,容易导致冲突(即不同的数据可能映射到相同的位置,导致频繁替换。

2-way(set associative cache) : 缓存被分为多个组,每组可以容纳两个块。因为每个组可以存放两个块,减少了冲突的概率。

对于更详细和专业的 Cache 介绍读者可以查阅相关更专业的资料。

例程使用的 ICache 默认模式为 1-way(direct mapped mode) ,那么我们将其改为 2-way(set associative cache) 能否提升 USB 写入的性能呢,从而达到与使能 DMA 同样的效果呢。

修改代码使能 ICACHE_2WAYS 模式,将 hhcd_USB_OTG_HS.Init.dma_enable=DISABLE.

下载代码测试发现,问题不再出现,交叉更换不同的 HUB 和 U 盘写入仍然正常。

除了前面提到的使能 DMA,ICACHE_2WAYS 使能以外,我们还可以做如下配置,来进一步提升写入性能。

以下是笔者向 U 盘连续地写入 1GByte 文件时所获得的实测性能,供参考如下:

4. 总结

可见,使能 USB_OTG_HS 的 DMA 和配置 ICache 工作模式为 2-way(set associative cache) ,均可以解决此问题,但只能定性此问题确实与 CPU 的性能相关。而多级 HUB 传输它需要额外的数据进行数据的包装,从而导致时间的增加。

相关推荐
LeoZY_4 天前
CH347应用 USB转JTAG功能之:probe-rs搭配CH347下载MCU命令全指南
单片机·嵌入式硬件·mcu·开源·github
sramdram5 天前
基于MCU微控制器的电子血压计应用解决方案
单片机·嵌入式硬件·mcu·mcu微控制器
南岸的水6 天前
BMS国标充电解析
单片机·嵌入式硬件·mcu
sramdram6 天前
低功耗国产蓝牙芯片,蓝牙MCU方案
单片机·嵌入式硬件·mcu·蓝牙mcu·蓝牙方案
Championship.23.2410 天前
Linux 3.0 USB机制深度解析:USB 3.0支持与传统外设驱动架构
linux·运维·架构·usb
EMTime15 天前
玲珑GUI-工程设置
单片机·mcu·ui·用户界面
ZenasLDR16 天前
Type-C接口iPad键盘皮套
接口·芯片·usb
smallerxuan16 天前
九、CherryUSB 设计架构与工作逻辑分析
usb·cherryusb·cherryusb分析
agathakuan16 天前
從零開始在家開發 IoT: Flash & Run 腳本解析(STM32 + WiFi HaLow)
stm32·mcu·iot
smallerxuan17 天前
二、USB协议中的设备类
usb·usb协议·usb设备类