|
我在 STM32F407 上搞了一套 USB DFU 主机类驱动。硬件上我把 USB‑C 线直接焊接到 D+、D‑、5V、GND 引脚。 小于等于 128 字节的传输,协议栈工作完全正常。但是当 我跟踪代码发现 HCTSIZ 寄存器的两个关键字段:
循环第 1 轮: i=15:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 2 i=31:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 1 循环第 2 轮: 初始状态:size = 128,cnt = 2 i=15:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 1 i=31:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 0 结果:传输完成,执行成功。
循环第 1 轮: i=15:写入 USBx_DFIFO;寄存器更新:size = 128,cnt = 3 i=31:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 2 i=47:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 1 循环第 2 轮(异常开始): 初始状态:size = 128,cnt = 2 i=15:写入 USBx_DFIFO;寄存器更新:size = 128,cnt = 2 i=31:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 1 i=47:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 1 最后一次写完数据包,cnt 没有发生变化。 循环第 3 轮(状态错乱,进入死循环): 传输被重新初始化为:size = 128,cnt = 3 cnt 被莫名重新设置为 3 i=15:写入 USBx_DFIFO;寄存器更新:size = 128,cnt = 3 i=31:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 3 cnt 锁死固定等于 3,不再递减 i=47:写入 USBx_DFIFO;寄存器更新:size = 64,cnt = 3 我把同一套 DFU 主机上层代码移植到 STM32G0C1CEU6,大数据包传输一切正常。应用层代码完全不变;二者最大硬件差异:F4 使用 FIFO 架构,G0 使用 PMA 内存架构,底层硬件驱动不同。 |
STM32F407全速USB 回复 STALL 握手包
STM32F405RG VCP 报错This device cannot start (code 10)
STM32F401RBT6 USB 大容量存储设备问题
USB OTG 主机枚举问题
STM32F042 在启动文件内跳转至 USB DFU Bootloader
B-L475E-IOT01A 无法枚举为 USB DFU 设备
USBX Audio Class frame done 不触发回调
STM3210C-EVAL USB 官方例程调试报错
STM32F103 全速 USB 大容量存储方案咨询
STM32H573ZI 全速 USB
微信公众号
手机版
可能是发生NAK 后,软件错误地把整个192B 传输重新提交了。这会引出两个现象:
1、HCTSIZ / PKTCNT 被重新写。
这时会看到,本来还剩一部分没发完,结果 PKTCNT 又回到 3。
2、NPTX FIFO 被重复灌数据。
因为同一段 192B 又被重新塞进FIFO,最后可能卡在 USB_WritePacket()。
原因很可能是控制 OUT 的NAK 重试逻辑有问题。
你要确认下,设备回了 NAK 之后,主机是不是把整段192B 又从头提交了一遍。
具体来说,就是观察在出错或被 NAK 后再次发送时,是否简单地再次SubmitRequest(192),并把 xfer_count 清零。
正常情况下,主机只应重试还没成功发送的那一包,而不是不管前面已经发出去多少,又把整段数据重新发一遍。