Восстановление USB-конечной точки после halt: CLEAR_FEATURE, циклы STALL, сбои bulk и сброс драйвера
Как отлаживать восстановление USB-конечной точки, CLEAR_FEATURE ENDPOINT_HALT, повторяющиеся циклы STALL, сбои bulk-передач, сбросы драйверов и баги стейт-машины прошивки.
Halt конечных точек USB — частая причина багов «один раз сработало, потом ломается». Bulk-передача встаёт в stall, драйвер сбрасывает halt, устройство снова ставит stall, и в итоге приложение сообщает о тайм-ауте, ошибке ввода-вывода, сбросе устройства или отключении. Пользователи ищут «USB endpoint halt», «CLEAR_FEATURE ENDPOINT_HALT», «USB STALL loop», «bulk endpoint stalled», «libusb clear halt», когда устройство не просто исчезает, а перестаёт принимать трафик на конкретной конечной точке.
Bus Scope полезен тем, что восстановление после halt — это последовательность, а не одиночное событие. Нужно увидеть первый STALL, запрос на восстановление от хоста, что устройство сделало после этого, и не вызвала ли ту же причину halt повторно.
Что значит endpoint halt
Halt конечной точки означает, что конечная точка остановлена и не может продолжать нормальные передачи, пока halt-условие не снято. Хост может послать:
CLEAR_FEATURE(ENDPOINT_HALT)
на нужную конечную точку. После этого data toggle на стороне устройства и его внутреннее состояние должны быть согласованы, чтобы передача возобновилась правильно.
Если прошивка сбрасывает только аппаратный флаг USB, но не своё внутреннее состояние протокола, следующая передача снова упадёт.
STALL vs тайм-аут
STALL — это явный сигнал. Тайм-аут означает, что за ожидаемое время нет завершения. Тайм-аут может случаться, потому что конечная точка не отвечала, устройство продолжало NAK-нуть или устройство отключилось.
Восстановление после halt начинается с STALL. Если хост не видит STALL и видит только тайм-аут, путь восстановления другой.
Halt bulk-конечной точки
Bulk-конечные точки часто уходят в halt, когда команда недействительна, фаза протокола нарушена или прошивка обнаружила ошибку.
Пример:
Host -> Device bulk OUT command
Device -> Host STALL on bulk IN
Host -> Device CLEAR_FEATURE(ENDPOINT_HALT)
Host retries bulk IN
Device stalls again
Такой паттерн говорит о том, что halt — это симптом состояния протокола устройства, а не просто транзитная ошибка шины.
Восстановление должно соответствовать направлению конечной точки
Адреса конечных точек включают направление. Endpoint 0x81 и endpoint 0x01 — это разные направления. Сброс halt на неправильной конечной точке не восстановит остановившийся pipe.
Проверьте:
- Какая конечная точка ставит stall?
- Направление IN или OUT?
- Сбросил ли хост halt на той же конечной точке?
- Возобновились ли передачи после clear?
- Корректно ли восстановились data toggle и состояние?
Это частая причина ложных сообщений «clear halt не сработал».
Повторяющиеся циклы STALL
Повторный STALL после clear обычно означает, что первопричина остаётся:
- Хост снова шлёт неподдерживаемую команду.
- Стейт-машина прошивки остаётся в ошибке.
- Устройство ожидает сброс перед повтором.
- Хост читает с неправильной конечной точки.
- Длина или контрольная сумма команды неверны.
- Data toggle/состояние конечной точки рассогласованы.
- Прошивка требует классовый/вендорный запрос перед возобновлением.
В трассе должна быть и команда перед первым STALL, а не только попытки восстановления.
Поведение драйвера при сбросе
Если восстановление через clear-halt не удаётся, драйвер может сбросить устройство. Это может скрыть исходную ошибку конечной точки. Пользователь видит переподключение или исчезновение устройства, но данные шины показывают, что настоящий первый сбой — это был цикл STALL.
Сохраните таймлайн:
- Последняя успешная команда.
- Первый STALL.
- Попытка clear halt.
- Повтор.
- Повторный STALL или тайм-аут.
- Сброс устройства или отключение.
Чек-лист отладки
Используйте такой сценарий:
- Определите конечную точку, которая ставит stall.
- Зафиксируйте направление и тип передачи.
- Изучите команду или передачу прямо перед STALL.
- Проверьте, посылает ли хост
CLEAR_FEATURE(ENDPOINT_HALT). - Подтвердите, что запрос адресует правильную конечную точку.
- Проверьте, возобновилась ли передача.
- Если STALL повторяется — изучите состояние протокола в прошивке.
- Ищите сброс устройства после неудачного восстановления.
- Сравните с заведомо работающей последовательностью команд.
- Сохраните достаточно контекста до STALL.
Итоговый диагноз
Восстановление USB-конечной точки после halt — это задача стейт-машины. CLEAR_FEATURE(ENDPOINT_HALT) может сбросить USB-условие halt, но не починит автоматически состояние протокола в прошивке, неправильные команды, неправильные конечные точки или retry-логику драйвера.
Bus Scope помогает показать полную последовательность halt и восстановления, чтобы сбои конечной точки диагностировались по реальному поведению USB.