Несовпадение max packet size конечной точки USB: отладка wMaxPacketSize, коротких пакетов, bulk-передач и багов буфера

Как отлаживать несовпадения max packet size USB-конечной точки, ошибки wMaxPacketSize в дескрипторе, короткие пакеты, сбои bulk-передач, отличия high-speed/full-speed и баги буфера прошивки.

max packet size, wMaxPacketSize, короткий пакет, bulk-передача, несовпадение дескриптора, баг прошивки, диагностика USB

wMaxPacketSize конечной точки USB выглядит как маленькое поле дескриптора, но неверное значение может сломать bulk-передачи, interrupt-репорты, работу high-speed, буферизацию прошивки и предположения драйвера хоста. Пользователи ищут «USB wMaxPacketSize mismatch», «USB short packet problem», «bulk transfer stops at 64 bytes», «USB endpoint packet size high speed full speed», «USB descriptor max packet size bug», когда передачи падают только на определённых размерах или скоростях.

Bus Scope полезен тем, что сбой виден только при одновременном сравнении дескриптора и пакетов передачи. Дескриптор может заявлять один размер пакета, а прошивка, хост-код или аппаратура конечной точки ведут себя так, как будто размер другой.

Что задаёт wMaxPacketSize

Каждый дескриптор конечной точки содержит wMaxPacketSize. Он сообщает хосту максимальный размер полезной нагрузки пакета для этой конечной точки. Типичные значения зависят от скорости и типа конечной точки.

Примеры:

  • Full-speed bulk-конечная точка часто использует 64 байта.
  • High-speed bulk-конечная точка часто использует 512 байт.
  • Interrupt-конечные точки варьируются по скорости и интервалу.
  • Isochronous-конечные точки используют размеры пакетов под полосу.

Если прошивка настроила буферы на 64 байта, а в дескрипторе 512 — хост может слать передачи, которые устройство не способно нормально обработать.

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

Баги max packet size могут выглядеть так:

  • Bulk-передача работает на маленьких сообщениях, но падает на больших.
  • Устройство работает на full-speed, но падает на high-speed.
  • Передача останавливается ровно на 64 байтах.
  • Хост бесконечно ждёт короткого пакета.
  • Прошивка получает данные в разорванном виде.
  • Устройство ставит stall на OUT-передачи.
  • IN-передачи возвращают усечённые данные.
  • Драйвер сообщает тайм-аут, хотя трафик идёт.
  • Составное устройство работает на одном интерфейсе, но не на другом.

Точное число байт — часто главная подсказка.

Поведение коротких пакетов

USB bulk-передачи часто используют короткие пакеты, чтобы показать конец передачи, когда запрошенная длина больше реальных данных. Если устройство возвращает ровно кратное max packet size число байт, хост может ждать дальше, если только протокол не задаёт длину отдельно или не отправляет ZLP (пакет нулевой длины).

Например:

max packet size: 64
payload length: 128
packets: 64 + 64
end condition: ambiguous unless length is known or ZLP is sent

Поэтому «USB short packet» и «USB zero length packet» — сильные поисковые запросы. Устройство может проходить простые тесты и зависать, когда длина полезной нагрузки приходится ровно на границу пакета.

Несовпадение high-speed и full-speed

Часть устройств корректно работает на full-speed, но ломается на high-speed. Причины:

  • Дескриптор high-speed заявляет 512 байт.
  • Буфер прошивки остаётся 64 байта.
  • На high-speed меняется выравнивание DMA.
  • FIFO конечной точки слишком мал.
  • Драйвер хоста рассчитывает на high-speed-пакетирование.
  • Дескриптор устройства отличается между режимами скорости.

Bus Scope помогает сравнить скорость перечисления, значения дескриптора конечной точки и реальное разбиение передач на пакеты.

Ошибки копирования дескрипторов

Команды прошивок часто копируют дескрипторы конечных точек между интерфейсами или режимами. Это создаёт тонкие баги:

  • Interrupt-конечная точка заявляет размер, как у bulk.
  • Размер OUT-конечной точки неожиданно отличается от IN.
  • Alternate setting имеет другой размер, а прошивка не перенастраивает конечную точку.
  • Деревья дескрипторов full-speed и high-speed не совпадают.
  • Соседние дескрипторы не соответствуют ожидаемой пропускной способности.

Правильный диагностический вид связывает адрес конечной точки с её дескриптором и каждой передачей по этой точке.

Баги буфера в прошивке

Даже при корректном дескрипторе прошивка может обрабатывать данные неправильно:

  • Считает, что один USB-пакет = одно сообщение приложения.
  • Не обрабатывает разорванные сообщения.
  • Теряет пакеты нулевой длины.
  • Считает короткий пакет ошибкой.
  • Перезаписывает приёмный буфер после первого пакета.
  • Падает, когда длина передачи равна max packet size.
  • Не делает flush IN-конечной точки после финального короткого пакета.

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

Предположения драйвера хоста

Код на хосте тоже может быть неправильным. Он может:

  • Запрашивать слишком маленький буфер.
  • Ожидать, что один вызов чтения равен одному сообщению устройства.
  • Игнорировать завершение по короткому пакету.
  • Использовать тайм-аут вместо фрейминга по длине.
  • Слать команду больше буфера прошивки.
  • Забывать про поведение ZLP.

Когда обе стороны кастомные, пакетная трасса становится контрактом.

Какие данные собирать

Для диагноза max packet size соберите:

  • Скорость устройства.
  • Дескриптор конечной точки.
  • Адрес конечной точки и направление.
  • wMaxPacketSize.
  • Запрошенный хостом размер передачи.
  • Реально наблюдаемые размеры пакетов.
  • Наличие короткого пакета или ZLP.
  • STALL, NAK, тайм-аут или reset после передачи.
  • Отличие перечисления между full-speed и high-speed.
  • Логи прошивки, если доступны.

Лучшие отчёты содержат точные счётчики байт. Поисковики тоже хорошо матчат такие практические детали.

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

Действуйте так:

  1. Определите дескриптор конечной точки.
  2. Зафиксируйте wMaxPacketSize.
  3. Сравните режим скорости.
  4. Пошлите полезные нагрузки меньше, равные и больше max packet size.
  5. Проверьте точные кратные max packet size.
  6. Ищите короткий пакет или ZLP.
  7. Проверьте, не ждёт ли хост после финального пакета.
  8. Сравните поведение IN и OUT-конечных точек.
  9. Проверьте смену alternate setting.
  10. Сохраните сбойную последовательность передач.

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

Баги max packet size USB-конечной точки — это проблемы дескриптора, передачи и контракта с прошивкой. Полезные данные — заявленный wMaxPacketSize, реальная пакетизация, поведение короткого пакета, обработка ZLP, режим скорости и сбои конкретной конечной точки.

Bus Scope помогает инженеру доказать, в чём именно баг — в дескрипторе, обработке буфера в прошивке, предположениях драйвера хоста или фрейминге передачи.