USB CDC ACM DTR 与 RTS 调试:SetControlLineState、串口打开、Bootloader 复位、数据丢失

USB CDC ACM DTR 和 RTS 控制线状态、SetControlLineState 请求、串口打开行为、Bootloader 复位触发、数据丢失的排查。

USB CDC ACM, DTR, RTS, Set Control Line State, 串口, Bootloader 复位, USB 诊断

USB CDC ACM 设备看起来像串口,但很多"串口 bug"其实是 USB 类控制 bug。用户搜 "CDC ACM DTR RTS"、"SetControlLineState USB"、"USB serial no data until DTR"、"Arduino resets when serial port opens"、"USB CDC bootloader reset"、"COM port opens but device does not respond" 的时候,端口在,但行为不对。

Bus Scope 在这个场景下有用,因为 DTR 和 RTS 不是应用层的魔法标志位。主机发的是类特定 Control Request,固件按这些请求做出反应。

SetControlLineState 干什么

CDC ACM 用一个通常叫 SetControlLineState 的类请求,传达控制线状态:

  • DTR:Data Terminal Ready
  • RTS:Request To Send

很多设备用这些 bit 做的事远比传统 Modem 行为多。固件可能:等 DTR 拉高才往外发、DTR 翻转就进 Bootloader、用 RTS 做流控语义。

常见症状

控制线问题表现为:

  • COM 端口打开了但收不到数据
  • 终端程序一连上设备才开始发
  • 串口监视器一开固件就 Reset
  • 端口开 / 关之后出现 Bootloader
  • DTR 一掉数据就停
  • RTS/CTS 流控选项改变了行为
  • Linux 工具能用、Windows 工具不行
  • Python 脚本和终端模拟器表现不一样

这些说法正好就是工程师在试图复现故障时的描述。

串口打开行为

不同的主机应用打开端口时设 DTR / RTS 的方式不一样。

例子:

  • 终端模拟器打开就置 DTR
  • 脚本打开端口但保持 DTR false
  • 固件升级工具把 DTR 翻转当 Reset 信号
  • 驱动根据流控设置 RTS
  • 应用关端口的时候意外把 DTR 拉低

包 trace 能展示真正的 Control Request 序列,而不是依赖应用层的假设。

Bootloader 复位模式

很多开发板用 DTR 或 RTS 翻转来复位进入 Bootloader。这对固件上传很方便,但在生产工具里就成了一种惊喜。

失败模式:

  • 一打开日志查看器设备就 Reset
  • 固件上传能用但普通串口连接失败
  • 设备是一种 USB 身份,Reset 之后重新枚举成 Bootloader
  • Reset 之后 Serial Number 或 Product String 变了
  • 应用丢了端口句柄

Bus Scope 应该保留 Control Request 和重新枚举序列。

等 DTR 才发数据

有些固件故意等 DTR 拉高才发数据。这会让一个工具看起来坏、另一个能用。

证据:

  • 主机打开 Bulk 或 Interrupt 端点
  • 没有 IN 数据发出
  • 主机发 SetControlLineState 把 DTR 置 true
  • 设备开始发送

这不是线材问题,也不一定是驱动 bug——这是固件策略。

RTS 和流控的混乱

RTS 可能被用作硬件流控,但很多 USB CDC 设备没有真正的 Modem 线。固件可能还是把 RTS 状态暴露给应用逻辑。

要回答的问题:

  • 主机有没有设 RTS?
  • 设备是不是要 RTS 才肯发?
  • 终端开了硬件流控之后,请求 bit 变了吗?
  • 固件忽略了 RTS 但文档说没忽略?
  • RTS 被当成 Bootloader 或模式选择信号在用?

包证据让你不用猜。

排查清单

按这个流程:

  1. 抓枚举
  2. 用出问题的应用打开串口
  3. 记录 CDC 类特定请求
  4. 找 SetControlLineState
  5. 解码 DTR 和 RTS bit
  6. 和一个能用的终端程序对比
  7. 看 DTR 之后数据有没有开始发
  8. 看翻转之后有没有 Reset 或重新枚举
  9. 对比 Windows 和 Linux 工具
  10. 把 Control Request 和最初几个数据包一起保留

最终诊断

USB CDC ACM DTR 和 RTS 的问题是类控制时序问题。端口在、驱动绑上了,固件仍然可能在等应用永远不会发的那条控制线状态。

Bus Scope 在 USB 协议层展示 SetControlLineState、DTR、RTS、串口打开行为、Bootloader 复位以及数据丢失的原因。