Отладка CDC ACM DTR и RTS: SetControlLineState, открытие COM-порта, reset загрузчика и пропавшие данные

Как отлаживать CDC ACM DTR и RTS, запросы SetControlLineState, поведение при открытии serial-порта, reset-триггеры загрузчика и пропавшие данные.

USB CDC ACM, DTR, RTS, set control line state, serial-порт, reset загрузчика, диагностика USB

USB CDC ACM-устройства выглядят как serial-порты, но многие баги «serial-порта» — на самом деле баги класс-управления USB. Пользователи ищут «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 — это не магические флаги приложения. Хост шлёт класс-управляющие запросы, и прошивка реагирует на эти запросы.

Что делает SetControlLineState

CDC ACM использует класс-запрос, обычно называемый SetControlLineState. Он передаёт состояние control line, такое как:

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

Многие устройства используют эти биты шире, чем традиционное модемное поведение. Прошивка может начать стримить только после установки DTR, войти в загрузчик при переключении DTR или использовать RTS для семантики flow-control.

Типичные симптомы

Проблемы с control line проявляются как:

  • COM-порт открыт, но данные не идут.
  • Устройство начинает слать только после подключения терминальной программы.
  • Прошивка сбрасывается при открытии serial-монитора.
  • Загрузчик появляется после open/close порта.
  • Данные останавливаются при падении DTR.
  • Изменение опции flow-control RTS/CTS меняет поведение.
  • Linux-инструмент работает, Windows-инструмент — нет.
  • Python-скрипт ведёт себя не так, как эмулятор терминала.

Эти формулировки совпадают с тем, как инженеры описывают симптомы, пытаясь воспроизвести сбой.

Поведение открытия serial-порта

Разные приложения по-разному ставят DTR и RTS при открытии порта.

Примеры:

  • Эмулятор терминала сразу устанавливает DTR.
  • Скрипт открывает порт, но оставляет DTR = false.
  • Инструмент обновления прошивки переключает DTR как сигнал сброса.
  • Драйвер ставит RTS по настройкам flow-control.
  • Приложение закрывает порт и неожиданно сбрасывает DTR.

Пакетная трасса покажет реальную последовательность управляющих запросов вместо предположений приложения.

Паттерны reset загрузчика

Многие отладочные платы используют переходы DTR или RTS для сброса в режим загрузчика. Это удобно для загрузки прошивки, но неожиданно в проде.

Паттерны сбоев:

  • Устройство сбрасывается каждый раз, когда открывается log-вьювер.
  • Загрузка прошивки работает, но обычное serial-соединение — нет.
  • Устройство появляется как одна USB-идентичность, сбрасывается, пере-нумеруется как загрузчик.
  • Serial-номер или строка продукта меняется после сброса.
  • Приложение теряет хэндл порта.

Bus Scope должен сохранить управляющий запрос и последовательность пере-нумерации.

Нет данных до DTR

Некоторые прошивки намеренно ждут DTR перед отправкой данных. Из-за этого один инструмент выглядит сломанным, а другой работает.

Доказательства:

  • Хост открывает bulk или interrupt-конечные точки.
  • IN-данных нет.
  • Хост шлёт SetControlLineState с DTR = true.
  • Устройство начинает передачу.

Это не проблема кабеля и не обязательно баг драйвера. Это политика прошивки.

Путаница с RTS и flow-control

RTS может использоваться под аппаратный flow-control, но у многих USB CDC-устройств реальных модемных линий нет. Прошивка всё равно может выставить RTS в логику приложения.

Вопросы:

  • Ставит ли хост RTS?
  • Требует ли устройство RTS перед передачей?
  • Меняет ли включение аппаратного flow-control в терминале биты запроса?
  • Игнорирует ли прошивка RTS, а документация утверждает обратное?
  • Используется ли RTS как сигнал загрузчика или mode-select?

Пакетные данные снимают догадки.

Чек-лист отладки

Используйте такой процесс:

  1. Захватите перечисление.
  2. Откройте serial-порт сбойным приложением.
  3. Зафиксируйте CDC класс-управляющие запросы.
  4. Найдите SetControlLineState.
  5. Декодируйте биты DTR и RTS.
  6. Сравните с работающим терминалом.
  7. Проверьте, начинаются ли данные после DTR.
  8. Проверьте, идёт ли reset или пере-нумерация после переключения.
  9. Сравните инструменты Windows и Linux.
  10. Сохраните управляющие запросы и первые пакеты данных вместе.

Итоговый диагноз

Проблемы USB CDC ACM DTR и RTS — это задачи последовательности класс-управления. Порт может существовать, драйверы привязаться, а прошивка ждёт состояния control line, которое приложение никогда не шлёт.

Bus Scope помогает показать SetControlLineState, DTR, RTS, поведение открытия serial-порта, reset загрузчика и причины пропавших данных на уровне USB-протокола.