Когда USB-хостам требуется пакет IN нулевой длины в конце передачи Control Read? - PullRequest
7 голосов
/ 18 сентября 2010

Я пишу код для устройства USB. Предположим, что USB-хост запускает передачу управляющего чтения для чтения некоторых данных с устройства, а количество запрашиваемых данных (wLength в пакете установки) кратно максимальному размеру пакета Endpoint 0. Затем, после того как хост получит все данные (в виде нескольких транзакций IN с пакетами данных максимального размера), он инициирует еще одну транзакцию IN, чтобы посмотреть, есть ли еще данные, хотя их не может быть больше?

Вот пример последовательности событий, которые меня интересуют:

  1. Процесс перечисления USB: максимальный размер пакета в конечной точке 0, как сообщается, равен 64.
  2. Транзакция SETUP-DATA-ACK запускает передачу управляющего чтения, wLength = 128.
  3. Транзакция IN-DATA-ACK доставляет первые 64 байта данных на хост.
  4. Транзакция IN-DATA-ACK доставляет на хост последние 64 байта данных.
  5. IN-DATA-ACK с пакетом данных нулевой длины? Эта транзакция когда-либо случалась?
  6. транзакция OUT-DATA-ACK завершает фазу состояния передачи; передача окончена.

Я проверил это на своем компьютере (Windows Vista, если это имеет значение), и получил ответ нет : хост был достаточно умен, чтобы знать, что с устройства больше нельзя получить данные, даже если все пакеты, отправленные устройством, были заполнены (максимально допустимый размер на конечной точке 0). Мне интересно, есть ли какие-нибудь хосты, которые не достаточно умны, и будут пытаться выполнить другую транзакцию IN и ожидать получения пакета данных нулевой длины.

Я думаю, что прочитал соответствующие части спецификаций USB 2.0 и USB 3.0 с usb.org, но я не нашел эту проблему решенной. Буду признателен, если кто-нибудь укажет мне правый раздел в любом из этих документов.

Я знаю, что пакет нулевой длины может быть необходим, если устройство решит отправить меньше данных, чем запрашиваемый хост в wLength.

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

Спасибо всем, кто может ответить на этот вопрос!

Ответы [ 4 ]

9 голосов
/ 20 апреля 2012

Внимательно прочитайте спецификацию USB:

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

  • Передал именно тот объем данных, который указан на этапе установки
  • Передает пакет с размером полезной нагрузки меньше, чем wMaxPacketSize, или передает пакет нулевой длины

Итак, в вашем случае, когда wLength == размер перевода, ответ НЕТ, вам не нужен ZLP.

В случае, если wLength> размер передачи и (размер передачи% ep0 size) == 0 ответ ДА, вам нужен ZLP.

5 голосов
/ 16 января 2011

Как правило, USB использует пакет, длина которого меньше максимальной, чтобы определить окончание передачи.Таким образом, в случае передачи, которая является целым кратным максимальной длины пакета, для разграничения используется ZLP.

Вы часто видите это в больших объемах труб.Например, если у вас есть передача 4096 байт, она будет разбита на целое число пакетов максимальной длины плюс один пакет нулевой длины.Если в драйвере SW установлен достаточно большой буфер приема, SW высокого уровня получает всю передачу сразу, когда происходит ZLP.

Передачи управления являются особым случаем, потому что они имеют поле wLength, поэтому ZLPне является строго обязательным.

Но я настоятельно рекомендую SW быть гибким в обоих случаях, так как вы можете увидеть различия с разными USB-хостами или низкоуровневыми драйверами HCD.

4 голосов
/ 03 января 2014

Я хотел бы расширить ответ MBR.Спецификация USB 2.0 в разделе 5.5.3 гласит:

Стадия передачи данных управления от конечной точки к хосту завершается, когда конечная точка выполняет одно из следующих действий:следующее:

  • Передал именно тот объем данных, который указан на этапе установки
  • Передает пакет с размером полезной нагрузки меньше wMaxPacketSize или передает пакет нулевой длины

Когда этап Data завершен, хост-контроллер переходит к этапу Status вместо продолжения другой транзакции данных. Если хост-контроллер не переходит на стадию состояния после завершения стадии данных, конечная точка останавливает конвейер, как было описано в разделе 5.3.2. Если полезная нагрузка данных, превышающая ожидаемую, получена изконечная точка, IRP для передачи управления будет прервана / удалена.

Я добавил акцент на одно из предложений в этой цитате, потому что оно, кажется, специально говорит, что должно делать устройство: оно должно "остановка канала, если хост пытается продолжить фазу данных после того, как это было сделано, и это делается, если все запрошенные данные были переданы (т. е. число переданных байтов больше или равно wLength).Я думаю, что остановка относится к отправке пакета STALL.

Другими словами, устройству не нужен пакет нулевой длины в этой ситуации, и фактически спецификация USB говорит, что он не должен предоставлять его.

1 голос
/ 21 сентября 2010

Вам не нужно.(*)

Весь смысл wLength в том, чтобы сообщить хосту максимальное количество байтов, которые он должен пытаться прочитать (но он может прочитать меньше!)

(*) Я видел устройстватот сбой, когда запросы IN / OUT были сделаны в неправильное время во время передачи управления (при отладке нашего хост-решения).Так что любой хост, делающий то, о чем вы беспокоитесь, убил бы эти устройства и, надеюсь, не на рынке.

...