Тайм-аут bulk-передачи USB: отладка High-Speed, Full-Speed, STALL, NAK и задержек прошивки
Как диагностировать тайм-ауты bulk-передачи USB, медленные чтения, stalled записи, поведение NAK, восстановление endpoint halt, несовпадение скорости и задержки прошивки по USB-доказательствам.
Bulk-передачи USB используются там, где важна корректность, а не фиксированный тайминг. Накопители, serial-адаптеры, отладочные пробники, утилиты прошивки, сканеры, вендорные устройства и многие продукты сбора данных используют bulk-конечные точки. Когда они ломаются, пользователи ищут «USB bulk transfer timeout», «bulk endpoint stalled», «USB read timeout», «USB write timeout», «libusb bulk transfer failed», «USB device stops responding during bulk transfer».
Приложение обычно видит тайм-аут или ошибку ввода-вывода. Шина может рассказать больше: устройство NAK-нуло слишком долго, конечная точка ставила stall, хост ретраил, устройство сбросилось, размер передачи неверный, скорость устройства ниже ожидаемой, или прошивка блокировала, пока готовила данные.
Bus Scope полезен тем, что сбои bulk-передач требуют данных на уровне конечной точки, а не просто стектрейса из приложения.
В чём сильны bulk-передачи
Bulk-передачи надёжны на уровне USB-протокола. Они используют доступную полосу и могут ретраить. Они хороши для перемещения больших данных, где задержка менее строгая, чем корректность.
Частые bulk-устройства:
- USB mass storage
- CDC serial адаптеры
- вендорные инструменты прошивки
- отладочные пробники
- измерительные устройства
- принтеры и сканеры
- некоторые устройства захвата
- data-pipes FPGA или микроконтроллеров
Так как bulk-передачи используют остаточную полосу шины, производительность может меняться в зависимости от другого USB-трафика и планирования хоста.
Тайм-аут не всегда означает потерю пакета
Тайм-аут bulk-передачи обычно значит, что запрос со стороны хоста не завершился в течение тайм-аута приложения. Это может произойти, даже если шина ведёт себя корректно.
Причины:
- У устройства нет готовых данных, и оно продолжает NAK-нуть.
- Прошивка занята и задерживает ответ.
- Конечная точка halted после STALL.
- Хост послал запрос не на ту конечную точку.
- Размер передачи не совпадает с ожиданием протокола.
- Устройство сбросилось или отключилось.
- Драйвер некорректно подал передачу.
- Full-speed путь слишком медленный для ожидаемой пропускной способности.
- Другое устройство потребляет полосу шины.
- Тайм-аут приложения слишком агрессивный.
Трасса должна показать, что из этого правдоподобно.
Поведение NAK
USB-устройства могут отвечать NAK, чтобы показать, что они временно не готовы. NAK — не обязательно ошибка. Это сигнал управления потоком.
Для bulk IN-конечной точки повторные NAK могут означать, что у устройства пока нет данных. Для bulk OUT-конечной точки NAK могут означать, что устройство пока не может принять данные.
Проблема в длительности и контексте. Несколько NAK — нормально. Непрерывные NAK до тайм-аута приложения значат, что либо устройство не стало готовым, либо хост ждал данные не в то время.
STALL и endpoint halt
STALL отличается от NAK. Обычно это значит, что конечная точка halted или запрос не поддерживается в данном контексте. Восстановление часто требует:
CLEAR_FEATURE(ENDPOINT_HALT)
Если хост не сбросит halt, дальнейшие передачи могут продолжать падать. Если конечная точка ставит stall сразу после clear, прошивка может отвергать последовательность команд.
Ищите:
- Первый STALL перед тайм-аутом.
CLEAR_FEATURE(ENDPOINT_HALT).- Возобновилась ли передача после clear.
- Одна и та же команда вызывает STALL каждый раз.
- Reset после повторных STALL.
Ожидания High-Speed vs Full-Speed
Скорость USB меняет реалистичную пропускную способность. Full-speed-устройство не может выдать high-speed-пропускную способность. High-speed-устройство может откатиться из-за кабеля, концентратора, порта, целостности сигнала или переговоров устройства.
Если приложение ждёт high-speed-производительности, а устройство перечислилось как full-speed, могут появляться тайм-ауты на больших передачах.
Проверьте дескрипторы, согласованную скорость, max packet size конечной точки и реальный темп передач. Не выводите скорость из формы разъёма или маркетингового ярлыка.
Протоколы команд в прошивке
Многие bulk-устройства реализуют на USB протокол команда/ответ. Хост пишет команду в bulk OUT и ждёт данных на bulk IN.
Тайм-ауты случаются, когда:
- Неверный формат команды.
- Устройство ожидает управляющий запрос перед bulk-передачей.
- Устройство шлёт статус на другую конечную точку.
- Хост читает слишком рано.
- Хост читает слишком много.
- Прошивка блокирует, пока обрабатывает команду.
- Устройство требует границу ZLP.
- Предыдущее ошибочное состояние не сброшено.
Пакетные данные показывают, проигнорировало ли устройство команду, ставило stall, приняло без ответа или ответило на другую конечную точку.
Размер bulk-передачи и короткие пакеты
USB bulk-протоколы часто используют короткие пакеты для сигнала конца передачи. Если хост ждёт фиксированную длину, а устройство шлёт короткий пакет, приложение может неверно интерпретировать результат. Если хост ждёт ещё данных после того, как устройство уже закончило передачу, может возникнуть тайм-аут на уровне приложения.
Ищите:
- Запрошенную длину передачи.
- Реально возвращённую длину.
- Короткий пакет.
- Zero-length packet.
- Фрейминг протокола поверх USB.
Это особенно важно в кастомных прошивках и инструментах на libusb.
Чек-лист отладки
Используйте такой процесс:
- Захватите перечисление и дескрипторы конечных точек.
- Подтвердите скорость устройства и max packet size конечной точки.
- Определите bulk IN и bulk OUT конечные точки.
- Захватите команду или передачу, которая тайм-аутит.
- Проверьте, возвращает ли конечная точка NAK, STALL, данные или отключение.
- Изучите восстановление
CLEAR_FEATURE(ENDPOINT_HALT), если был STALL. - Сравните запрошенную и реальную длину.
- Проверьте, отправляет ли устройство короткий или ZLP-пакет.
- Сравните прямой порт против концентратора и high-speed против full-speed пути.
- Сопоставьте с логами прошивки, если доступны.
Итоговый диагноз
Тайм-аут bulk-передачи USB — это не один баг. Это может быть нормальное NAK-поведение, превысившее тайм-аут приложения; не восстановленный endpoint STALL; прошивка, которая не ответила; скорость ниже ожидаемой; неверный фрейминг протокола; или сброс устройства.
Bus Scope помогает тем, что показывает последовательность на уровне конечной точки, и тайм-аут становится диагностируемыми USB-доказательствами, а не общей ошибкой ввода-вывода.