USB DFU 固件升级失败:Bootloader 模式、控制传输、超时与重连排查
USB DFU 固件升级失败、Bootloader 检测、设备重连、控制传输 STALL、超时、驱动绑定失败——升级工具看不到的 USB 状态机。
固件升级失败的压力很大——设备可能消失、进入 bootloader、以不同的 VID/PID 重连、卡在"初始化 / 擦除 / 下载 / 重启"某一个阶段。用户搜 "USB DFU 失败"、"固件升级卡在初始化"、"USB Bootloader 检测不到"、"找不到 DFU 设备"、"固件升级超时"——因为升级工具几乎不会展示 USB 状态机。
USB Device Firmware Upgrade 通常建立在 Control Transfer 和设备状态转移之上。升级工具可能:和正常应用固件对话 → 命令重启进入 Bootloader → 等待另一台 USB 设备枚举 → 发送固件块 → 请求状态 → 命令 detach 或 reset。
Bus Scope 在这个场景下有用——从一开始抓,每一步在总线上都是可见的。
固件升级常常涉及两台设备
很多产品在正常运行时枚举成一台 USB 设备,进入 Bootloader 后又是另一台。VID/PID、产品字符串、接口、驱动绑定都可能变。
大致流程可能是:
- 正常设备已连接
- 升级工具发"进入 Bootloader"命令
- 设备断开
- Bootloader 设备枚举
- 升级工具发 DFU Download 块
- 设备上报状态
- 设备 Reset 回正常模式
用户在设备消失后才开始抓,那段关键的转移就看不到了。
常见失败点
DFU 升级失败于:
- Bootloader 模式根本没进
- Bootloader 枚举了但驱动没绑
- 升级工具认一种 VID/PID,设备暴露的却是另一种
- Control Transfer STALL
- 固件块大小不对
- 设备擦除时超时
- 状态轮询太凶
- 下载过程中设备断连
- 线材或供电问题导致复位
- 安全/版本校验拒收固件
升级工具可能把这些全部报告成"固件升级失败"。
Control Transfer 证据
DFU 类操作走 Control Transfer。Trace 能看出升级工具是不是真的发了 Download 数据、请求了状态、清了状态,或者撞上了 STALL。
要看的:
DFU_DNLOADDFU_UPLOADDFU_GETSTATUSDFU_CLRSTATUSDFU_ABORT- 设备 Reset 或断连
- 端点 0 上的 STALL
如果 Control Transfer 每次都在同一个块上 STALL,嫌疑就在固件镜像合法性、块大小、Flash 擦写行为,或者 Bootloader 本身的 bug。
重连时序
进入 Bootloader 之后,升级工具必须等重新枚举。如果它搜得太早,可能报"找不到设备"——其实 Bootloader 一秒后就出来了。
总线 trace 能把时序摆出来:
- 正常设备的 detach 时间
- Bootloader 的 attach 时间
- 描述符读取
- 驱动绑定
- 第一条 DFU 请求
有了这些证据,就能区分是升级工具超时还是设备故障。
驱动绑定问题
在 Windows 上,Bootloader 需要的驱动可能和正常设备不同。在 Linux 上,不同 VID/PID 的权限可能不一样。在 macOS 上,类行为也可能不一样。
如果 Bootloader 枚举正常但升级工具打不开,问题在 USB 枚举之上。如果 Bootloader 根本没枚举,先去查固件、线材、Reset、供电。
排查清单
按这个流程:
- 在升级工具启动之前就开始抓
- 记录正常设备的描述符
- 抓"进入 Bootloader"命令
- 观察断连和 Bootloader 重新枚举
- 记录 Bootloader 的 VID/PID 和描述符
- 检查 DFU Control Transfer
- 找第一个 STALL、超时、Reset 或缺响应
- 如果可复现,对比失败时的块号
- 检查枚举后的驱动绑定和权限
- 在裁剪之前保留完整的升级时间线
最终诊断
USB DFU 失败是状态机失败。根因可能在 Bootloader 进入、重新枚举、驱动绑定、DFU Control Transfer 行为、块大小、Flash 时序、固件镜像校验或 Reset 时序。
Bus Scope 把固件升级展现成一份 USB 证据,而不是一个停在某处的进度条。