[STM32F4] Nucleo‑144 F439ZI OTG FS 模式开启 DMA 后设备无法枚举

[复制链接]
51|10
咚了个咚 发表于 2026-9-19 08:44 | 显示全部楼层 |阅读模式
我在 OTG‑FS 模式下启用 DMA。
我修改了驱动文件 `Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_pcd.c`:

#if defined (USB_OTG_FS)
/* Disable DMA mode for FS instance */
if (USBx == USB_OTG_FS)
{
   hpcd->Init.dma_enable = ENABLE; //FGE: try to use OTG FS with DMA enabled
}
#endif /* defined (USB_OTG_FS) */

但是设备无法完成枚举。以上就是我在 CubeMX 生成代码上所做的唯一一处改动。

公羊子丹 发表于 2026-9-19 15:40 | 显示全部楼层
你改的那行正好是 ST 特意为 FS 实例禁 DMA 的地方——注释写得很直白'Disable DMA mode for FS instance'。F4 的 OTG-FS 内核(共享的 OTG IP)**在 FS 模式下 DMA 支持是有条件限制的**,ST 默认禁掉是有原因的。强行改 ENABLE 导致枚举失败,说明这条路径没被验证过。
周半梅 发表于 2026-9-19 15:41 | 显示全部楼层
我赌根因是 **OTG-FS 的 DMA 需要专用 RAM 或特定 FIFO 配置**。OTG IP 的 DMA 不是通用 DMA,是内建的专用 DMA,它要求端点的 FIFO 分配和 total FIFO size 满足特定约束(dma_enable=1 时 FIFO 分配规则和中断模式不同)。你只改了 dma_enable 没重配 FIFO,自然不工作。
帛灿灿 发表于 2026-9-19 15:42 | 显示全部楼层
补充:F4 的 OTG_FS 用内建 DMA 时,有个已知限制——**FS 模式下 DMA 只支持特定端点/方向组合**,而且 F4 的 OTG 内建 DMA 在 FS 下的表现和 HS 不同。ST 在 HAL 里禁它正是因为这个。如果你非要 DMA,建议改用 HS 实例(USB_OTG_HS)配 ULPI,那才是 DMA 的主场。
童雨竹 发表于 2026-9-19 15:43 | 显示全部楼层
想问下你为什么要在 FS 上开 DMA?如果是嫌中断模式 CPU 占用高,可以先用'中断模式但优化 FIFO'看看够不够。FS 只有 12Mbps,DMA 省的那点 CPU 开销有限,反而是 FS+DMA 这种非主流组合坑多。先评估需求值不值得。
万图 发表于 2026-9-19 15:43 | 显示全部楼层
从 HAL 代码看,`hpcd->Init.dma_enable` 只是 HAL 层的开关,真正让 OTG 内建 DMA 工作还需要 **GAHBCFG 寄存器的 DMAEN 位被正确设置**,以及端点的 DMA 地址(DOEPDMA/DIEPDMA)由 HAL 填入。如果你只改了这个 Init 字段,但 HAL 的 DMA 使能路径没走通,枚举时端点没搬数据就卡住。
Wordsworth 发表于 2026-9-19 15:44 | 显示全部楼层
测试建议:改完后用调试器看 OTG_FS 的 GAHBCFG 寄存器 DMAEN 位有没有被置 1,以及枚举失败时停在哪个中断/状态。如果 DMAEN 没置上,说明 HAL 没真正启用 DMA;如果置上了但数据没搬,那是端点 DMA 地址/FIFO 问题。分清是'开关没生效'还是'生效了但不对'。
Bblythe 发表于 2026-9-19 15:45 | 显示全部楼层
我之前看过 ST 社区有讨论,F4 的 OTG-FS 内建 DMA 在 device 模式下的支持是不完整的,尤其 ISO 端点和某些枚举阶段。所以 ST 干脆禁掉。如果你只是想加速 bulk 端点,可以在不改 HAL 默认的前提下,只在 bulk 传输时用 DMA,控制传输维持中断模式,但这也得改不少代码。
Pulitzer 发表于 2026-9-19 15:46 | 显示全部楼层
补充个方向:如果你的目标是提高 USB 吞吐,与其折腾 FS+DMA,不如考虑换到 **HS 模式 + FIFO 双缓冲**,或者优化现有的中断模式(增大端点 FIFO、用双缓冲 PingPong)。F4 FS 12Mbps 的现实吞吐本来就不高,DMA 的收益很有限。
Uriah 发表于 2026-9-19 15:47 | 显示全部楼层
问一句:你枚举失败是设备完全不被识别,还是识别了但枚举中途失败?完全不被识别说明底层 DP 上拉/时钟就断了(DMA 改动影响了启动);中途失败说明枚举到某个请求时数据没搬(DMA 路径问题)。这两种指向不同,先确认。
Clyde011 发表于 2026-9-19 15:47 | 显示全部楼层
结论:ST 在代码里明说'FS instance 禁用 DMA',你把它打开属于走进未验证区域。FS+内建 DMA 在 F4 上不是官方支持组合,建议要么回到中断模式(用 FIFO 优化提性能),要么改用 HS 实例。真要在 FS 上用 DMA,得深入 OTG 内建 DMA 的 FIFO/端点配置,难度和收益不成正比。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

201

主题

210

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0