Отладка HID report descriptor: почему устройство перечисляется, а хост читает неверные данные

Как диагностировать ошибки HID report descriptor, из-за которых USB-устройство успешно перечисляется, но ведёт себя некорректно на хосте.

USB, HID, report descriptor, прошивка, отладка HID

HID привлекателен тем, что многие устройства могут работать без кастомных драйверов. Клавиатуры, датчики, ручки, сканеры штрихкодов, пульты и вендорные HID-устройства — все выигрывают от стандартного стека хоста. Но HID также переносит сложность в report descriptor. Устройство может корректно перечислиться и всё равно слать данные, которые хост интерпретирует неправильно.

Это одна из самых частых ловушек USB-прошивок: успешное перечисление принимают за корректность HID.

Report descriptor задаёт контракт данных

HID report descriptor говорит хосту, как интерпретировать байты. Он задаёт usages, размеры репортов, их количество, логические диапазоны, физические диапазоны, коллекции и report IDs. Если дескриптор говорит одно, а прошивка шлёт другое, хост следует дескриптору.

Частые проблемы:

  • прошивка шлёт 8 байт, а дескриптор описывает 7
  • report ID отсутствует или лишний
  • знаковые значения описаны как беззнаковые
  • logical min/max не совпадает с реальным диапазоном
  • usage page неверный
  • неверно посчитан padding
  • несколько репортов сбивают с толку раскладкой
  • input и output репорты перепутаны

Симптом на стороне приложения — неверные значения, потерянные кнопки, игнорируемые репорты или эпизодические чтения.

Захватите дескриптор и репорты вместе

Отлаживать HID только по report descriptor — неполно. Отлаживать только по payload-байтам — тоже неполно. Нужно и то, и другое.

Полезный HID-захват показывает:

  • device descriptor
  • configuration и interface descriptors
  • HID descriptor
  • запрос и ответ report descriptor
  • interrupt IN-репорты
  • interrupt OUT-репорты, если используются
  • управляющие передачи для feature reports
  • report IDs и длины полезной нагрузки

Тогда инженер может сравнить заявленную раскладку с реальными байтами. Если дескриптор говорит Report Count 3, а в interrupt-пayload четыре значения, захват должен это сделать видимым.

Поведение хоста может быть корректным, даже когда выглядит неверным

Разработчики прошивок иногда думают, что хост теряет данные. В реальности хост может парсить согласно полученному дескриптору. Если в дескрипторе объявлен padding или другой report ID, данные могут выглядеть сдвинутыми, усечёнными или игнорируемыми.

Поэтому хороший отчёт поддержки должен включать сырые байты. Декодированная интерпретация полезна, но сырые байты снимают споры. Вопрос в том:

  • что отправила прошивка?
  • что объявила прошивка?
  • что запросил хост?
  • что хост получил?

Это правильная граница для отладки HID.

Составные HID-устройства требуют дополнительной аккуратности

Составные устройства могут выставлять HID плюс CDC, накопитель или вендорные интерфейсы. HID-часть может быть сама по себе корректной, но страдать от ошибок нумерации интерфейсов, назначения конечных точек или полной длины дескриптора.

Для отладки составного HID изучите:

  • interface association, если есть
  • номер интерфейса
  • уникальность адресов конечных точек
  • местоположение HID-дескриптора
  • длину report descriptor
  • маршрутизацию классовых запросов

Если хост запрашивает report descriptor с неправильного интерфейса или получает неверную длину, дальнейший репортный трафик становится обманчивым.

Место Bus Scope

Bus Scope создан для команд прошивок и устройств, которым нужна отладка USB через доказательства. Для случаев с HID report descriptor он позволяет инженеру изучать дерево дескрипторов, сырые байты, трафик по конечным точкам и сохранённый .bscope-сеанс вместе.

Практический результат — отчёт, который говорит:

  • report descriptor был запрошен и возвращён
  • длина репорта, заявленная дескриптором
  • реальная длина interrupt payload
  • поведение report ID
  • несоответствие или согласованность между объявлением и трафиком
  • следующее действие в дескрипторе прошивки, упаковке репорта или ожиданиях хостового парсера

Это намного полезнее, чем «HID-устройство не работает». Превращает расплывчатую проблему ввода в конкретное рассогласование USB-контракта.