Лекция
Это продолжение увлекательной статьи про usb.
...
запрошенных данных, передала пакет меньше, чем максимальный размер оконечной точки, передала пакет нулевой длины.
На диаграмме показан формат транзакций bulk IN и bulk OUT.
Bulk IN: когда хост готов принять данные bulk, он выдает токен IN. Если функция принимает токен IN с ошибкой, она игнорирует пакет. Если токен принят корректно, функция может ответить либо пакетом DATA (содержащим отправляемые данные bulk), либо пакетом stall, (показывающим, что конечная точка имеет ошибку), либо пакетом NAK (показывающим, что конечная точка в работе, но у нее пока нет данных для отправки).
Bulk OUT: когда хост хочет отправить функции пакет bulk data, он выдает токен OUT, за которым идет data пакет, содержащий данные bulk. Если любая часть токена OUT или пакета data повреждена, функция игнорирует пакет. Если буфер конечной точки функции пуст, функция вдвигает данные в буфер конечной точки и выдает ACK, информируя хост об успешно принятых данных. Если буфер конечной точки функции не пуст по причине обработки предыдущего пакета, функция возвращает NAK. Однако если конечная точка в состоянии ошибки, и ее halt-бит установлен, функция возвращает STALL.
Управление полосой пропускания
Хост отвечает за управление полосой пропускания шины. Это происходит при энумерации, и конфигурировании изохронных конечных точек и конечных точек interrupt через операции на шине. Спецификация накладывает ограничения на шину, которые разрешают выделение не более 90% всех фреймов для периодических передач (Interrupt или Isochronous) на шине full speed. На шине high speed это ограничение уменьшено - не более 80% микрофреймов можно выделить для периодических передач.
Таким образом, очевидно - если у Вас есть шина, очень нагруженная периодическими передачами, то оставшиеся 10% оставлены для передач управления (control transfers), и как только они будут распределены (обработаны), передачи bulk получат оставшуюся часть полосы.
Все устройства USB имеют иерархию дескрипторов, которые описывают информацию для хоста – такую, как например что это за устройство, кто его изготовил, какую версию USB поддерживает устройство, какими способами устройство может быть сконфигурировано, количество конечных точек и их типы и т. д.
Наиболее общие дескрипторы USB следующие:
Устройства USB могут иметь только один дескриптор устройства (device descriptor). Дескриптор устройства включает в себя такую информацию, как поддерживаемую устройством ревизию USB, Product ID (PID, идентификатор продукта), Vendor ID (VID, идентификатор производителя), используемые для загрузки соответствующего устройству драйвера, и количество возможных конфигураций устройства. Число конфигураций указывает, сколько имеется ответвлений по дескрипторам конфигурации.
Дескриптор конфигурации (configuration descriptor) указывает величину потребляемой мощности от шины, питается ли устройство от собственного источника (self powered) либо от шины USB (bus powered) и количество интерфейсов, которые есть у конфигурации. Когда устройство проходит энумерацию, хост читает дескриптор устройства и принимает решение, какую конфигурацию применить. Хост может разрешить только какую-то одну из конфигураций.
Например, возможно существование конфигурации с высоким потреблением мощности от шины, и есть конфигурация с собственным источником питания. Если устройство подсоединено к хосту-десктопу с сетевым блоком питания, драйвер может выбрать конфигурацию с высоким потреблением мощности от шины, несмотря на то, что устройство подключено к собственному источнику, а в случае подсоединения к хосту-ноутбуку (при питании его от аккумултора) драйвер может принудительно выбрать конфигурацию с собственным блоком питания, что потребует от пользователя обязательного подключения внешнего блока питания для USB-устройства.
Параметры настройки конфигураций не ограничены различиями мощности. Каждая конфигурация может быть настроена на одинаковое питание, но иметь разные интерфейсы или наборы конечных точек. Однако нужно отметить, что изменение конфигурации требует, чтобы вся деятельность по каждой конечной точке остановилась. В то время как USB предлагает эту возможность, у очень немногих устройств есть больше чем 1 конфигурация.
Дескриптор интерфейса можно рассматривать как заголовок или группирование конечных точек в функциональную группу, выполняющую единственную особенность (feature) устройства. Например у Вас может быть многофункциональное устройство факса/сканера/принтера. Дескриптор интерфейса 1 может описывать конечные точки функции факса, дескриптор интерфейса 2 может описывать функцию сканера, и дескриптор интерфейса 3 может описывать функцию принтера. В отличие от дескриптора конфигурации, здесь нет ограничений на количество одновременно разрешенных интерфейсов. У устройства могут быть 1 или много интерфейсов, разрешенных одновременно.
Дескрипторы интерфейса имеют поле bInterfaceNumber, указывающее номер интерфейса, и поле bAlternateSetting, которое разрешает интерфейсу поменять установки на лету. Например, у Вас есть устройство с двумя интерфейсами – интерфейс 1 и интерфейс 2. У интерфейса 1 поле bInterfaceNumber установлено в 0, что показывает – это первый дескриптор интерфейса, и поле bAlternativeSetting, установленное в 0. У интерфейса 2 поле bInterfaceNumber установлено в 1, что показывает - это второй интерфейс, и поле bAlternativeSetting установленное в 0 (значение по умолчанию). Мы могли бы добавить сюда другой дескриптор, у которого поле bInterfaceNumber также установлено в 1 (показывает, что это второй интерфейс), но на этот раз поле bAlternativeSetting установлено в 1, что показывает – дескриптор интерфейса может иметь альтернативную настройку, взятую из другого описателя интерфейса 2.
Когда эта конфигурация разрешена, используются первые два дескриптора интерфейса, у которых поле bAlternativeSettings равно 0. Однако во время работы хост может послать запрос SetInterface, направленный на интерфейс с номером 1 (второй интерфейс) с альтернативной настройкой 1, что разрешает другой дескриптор интерфейса.
Это дает преимущество при использовании двух конфигураций – мы можем передавать данные через интерфейс 0, и в то же время менять настройки конечной точки, связанной с интерфейсом 1, не мешая работе интерфейса 0.
Каждый дескриптор конечной точки используется для указания типа передачи, направления, интервала опроса (polling interval) и максимального размера пакета для каждой конечной точки. Конечная точка 0 всегда подразумевается по умолчанию точкой для управления, и поэтому она не имеет дескриптора.
Композиция дескрипторов USB
Все дескрипторы имеют общий формат. Первый байт указывает длину дескриптора в байтах, второй байт показывает тип дескриптора. Если длина описателя будет меньшей, чем определено в спецификации, то главный компьютер должен проигнорировать его. Однако, если размер больше ожидаемого, хост будет игнорировать дополнительные байты, и будет искать следующий дескриптор в конце возвращенной действительной длины.
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bLength |
1 |
Число |
Размер дескриптора в байтах |
1 |
bDescriptionType |
1 |
Константа |
Тип дескриптора |
2 |
... |
n |
|
Начало параметров дескриптора |
Дескрипторы устройства
Дескриптор устройства для устройства USB представляет само устройство в целом. Как следствие – устройство USB может иметь только один дескриптор устройства. Этот дескриптор указывает некоторые основные (несомненно важные) сведения об устройстве, такие как поддерживаемая версия USB, максимальный размер пакета, идентификаторы ID вендора и продукта (VID и PID) и количество возможных конфигураций, которые может иметь устройство. Формат дескриптора устройства показан далее.
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bLength |
1 |
Число |
Размер дескриптора в байтах (для дескриптора устройства размер 18 байт) |
1 |
bDescriptorType |
1 |
Константа |
Тип - Device Descriptor (0x01) |
2 |
bcdUSB |
2 |
BCD |
Номер спецификации USB, с которой совместимо устройство. |
4 |
bDeviceClass |
1 |
Class |
Код класса (назначается организацией USB Org) |
5 |
bDeviceSubClass |
1 |
SubClass |
Код подкласса (назначается организацией USB Org) |
6 |
bDeviceProtocol |
1 |
Протокол |
Код протокола (назначается организацией USB Org) |
7 |
bMaxPacketSize |
1 |
Число |
Максимальный размер пакета для конечной точки 0. Допустимые размеры 8, 16, 32, 64 |
8 |
idVendor |
2 |
ID |
Vendor ID, VID (назначается организацией USB Org) |
10 |
idProduct |
2 |
ID |
Product ID, PID (назначается организацией - производителем) |
12 |
bcdDevice |
2 |
BCD |
Device Release Number (номер версии устройства) |
14 |
iManufacturer |
1 |
Индекс |
Индекс строки, описывающей производителя |
15 |
iProduct |
1 |
Индекс |
Индекс строки, описывающей продукт |
16 |
iSerialNumber |
1 |
Индекс |
Индекс строки, содержащей серийный номер |
17 |
bNumConfigurations |
1 |
Целое |
Количество возможных конфигураций |
Дескрипторы конфигурации
Устройство USB может иметь несколько различных конфигураций, хотя большинство устройств просты и имеют только одну конфигурацию. Дескриптор конфигурации указывает, как устройство запитывается, какое у него максимальное энергопотребление, количество интерфейсов, которое имеет устройство. Поэтому для устройства возможно иметь 2 конфигурации – одну для питания от шины, другую для питания от основного (внешнего) источника. Поскольку это – заголовок к дескрипторам интерфейса, возможно также иметь разные конфигурации для различных режимов передачи.
Как только все конфигурации прочитаны и проанализированы хостом, он посылает команду SetConfiguration с ненулевым значением, которое соответствует bConfigurationValue одной из конфигураций. Это используется для выбора нужной конфигурации.
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bLength |
1 |
Число |
Размер дескриптора в байтах |
1 |
bDescriptorType |
1 |
Константа |
Дескриптор конфигурации (0x02) |
2 |
wTotalLength |
2 |
Число |
Полная длина возвращаемых данных в байтах |
4 |
bNumInterfaces |
1 |
Число |
Количество интерфейсов |
5 |
bConfigurationValue |
1 |
Число |
Величина, используемая как аргумент для выбора этой конфигурации |
6 |
iConfiguration |
1 |
Индекс |
Индекс строкового дескриптора, описывающего эту конфигурацию |
7 |
bmAttributes |
1 |
Набор бит (Bitmap) |
D7 зарезервировано, установлено в 1. (USB 1.0 Bus Powered) |
8 |
bMaxPower |
1 |
мА |
Максимальное энергопотребление в единицах 2 мА |
Дескрипторы интерфейса
Дескриптор интерфейса можно рассматривать как заголовок собрание конечных точек, объединенных в функциональную группу для реализации (feature) устройства. Дескриптор интерфейса имеет следующий формат.
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bLength |
1 |
Число |
Размер дескриптора в байтах (9 байт) |
1 |
bDescriptorType |
1 |
Константа |
Дескриптор интерфейса (0x04) |
2 |
bInterfaceNumber |
1 |
Число |
Количество интерфейсов |
3 |
bAlternateSetting |
1 |
Число |
Величина, используемая для выбора альтернативной установки |
4 |
bNumEndpoints |
1 |
Число |
Количество конечных точек, используемых в интерфейсе |
5 |
bInterfaceClass |
1 |
Класс |
Код класса (назначается организациейUSB Org) |
6 |
bInterfaceSubClass |
1 |
Подкласс (SubClass) |
Код подкласса (назначается организациейUSB Org) |
7 |
bInterfaceProtocol |
1 |
Протокол |
Код протокола (назначается организациейUSB Org) |
8 |
iInterface |
1 |
Индекс |
Индекс строкового дескриптора, описывающего этот интерфейс |
Дескрипторы конечной точки
Дескрипторы конечной точки используются для описания конечных точек, отличных от конечной точки 0. Конечная точка 0 всегда используется как конечная точка управления, и она конфигурируется сразу автоматически, даже перед запросом информации всех дескрипторов. Хост использует информацию, полученную из описателей конечных точек, чтобы определить требования по полосе пропускания шины.
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bLength |
1 |
Число |
Размер дескриптора в байтах (7 байт) |
1 |
bDescriptorType |
1 |
Константа |
Дескриптор конечной точки (0x05) |
2 |
bEndpointAddress |
1 |
Конечная точка |
Адрес конечной точки |
3 |
bmAttributes |
1 |
Набор бит (Bitmap) |
биты 0..1 тип передачи |
4 |
wMaxPacketSize |
2 |
Число |
Максимальный размер пакета этой конечной точки, подходящий для отправки или приема |
6 |
bInterval |
1 |
Число |
Интервал для того, чтобы опросить передачи данных конечной точки. Указывается в количестве фреймов. Поле игнорируется для конечныйх точек Bulk и Control. Для конечных точек Isochronous должно быть равно 1 и для конечных точек interrupt может лежать в диапазоне 1..255. |
Строковые дескрипторы
Строковые дескрипторы предоставляют информацию в формате, удобном для чтения человеком, и их указывать необязательно. Если строковые дескрипторы не используются, поле индекса строки дескриптора должно быть установлено в 0, что указывает на отсутствие стркового дескриптора.
Строки закодированы в формате Unicode, и разрабатываемое устройство USB может быть изготовлено с поддержкой многих языков. Строка с индексом 0 должна вернуть список поддерживаемых языков. Список ID языков для USB может быть найден в документе Universal Serial Bus Language Identifiers (LANGIDs) version 1.0.
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bLength |
1 |
Число |
Размер дескриптора в байтах |
1 |
bDescriptorType |
1 |
Константа |
Строковый дескриптор (0x03) |
2 |
wLANGID |
2 |
Число |
Код поддерживаемого языка 0 |
4 |
wLANGID |
2 |
Число |
Код поддерживаемого языка 1 |
n |
wLANGID[x] |
2 |
Число |
Код поддерживаемого языка x |
Вышеупомянутый строковый дескриптор показывает формат строкового дескриптора 0. Хост должен прочитать этот дескриптор, чтобы определить, какие языки поддерживаются устройством. Если язык поддерживается, хост может запросом Get Descriptor(String) сослаться на него путем отсылки ID языка в поле wIndex.
Все последующие строки имеют формат:
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bLength |
1 |
Число |
Размер дескриптора в байтах |
1 |
bDescriptorType |
1 |
Constant |
Строковый дескриптор (0x03) |
2 |
bString |
n |
Unicode |
Строка, закодированная в Unicode |
Пакет Setup
Любое устройство USB должно ответить на пакеты установки (setup) по каналу по умолчанию (default pipe, конечная точка 0). Пакеты setup используются для обнаружения и конфигурирования устройства, и выполняют общие функции, такие как установка адреса устройства USB, запрос описателя устройства или проверка состояния конечной точки.
USB-совместимый хост предполагает, что все запросы будут обработаны в пределах максимального периода 5 секунд. Также определены более строгие лимиты времени для определенных запросов:
Эти периоды времени ожидания являются весьма приемлемыми для даже самого медленного из устройств, но могут быть ограничением во время отладки. Невозможно обеспечить 50 мс для многих отладчных символов, отправляемых на скорости 9600 bps через асинхронный последовательный порт, или во внутрисхемных отладчиках/эмуляторах при выполнении программы по шагам или при остановке по точке останова для просмотра внутренних регистров и переменных. Поэтому USB требует специальной техники отладки в отличие от других проектов на микроконтроллерах.
Бегло просматривая XP DDK, я заметил, что Host Controller Driver теперь имеет команду USBUSER_OP_SEND_ONE_PACKET, которая прокомментирована так:"Это API используется для реализации 'пошаговой отладки' в инструменте разработки транзакций USB (USB transaction development tool)." Такой инструмент еще не был выпущен. Мы можем только надеяться, что скоро его увидим.
Каждый запрос начинается с пакета Setup длиной 8 байт, который имеет следующий формат:
Смещ. |
Поле |
Размер |
Значение |
Описание |
0 |
bmRequestType |
1 |
Набор битов (BitMap) |
D7 направление передачи фазы данных |
1 |
bRequest |
1 |
Значение |
Запрос |
2 |
wValue |
2 |
Значение |
Значение |
4 |
wIndex |
2 |
Индекс или смещение |
Индекс |
6 |
wLength |
2 |
Счетчик |
Если это фаза данных, то количество байт данных для передачи |
Поле bmRequestType определит направление запроса, тип запроса и назначенного получателя. Поле bRequest определит делаемый запрос. Поле bmRequestType анализируется, и выполнение ответвляется на несколько обработчиков, таких как Standard Device request handler (стандартный обработчик запроса устройства), Standard Interface request handler (стандартный обработчик запроса интерфейса), Standard Endpoint request handler (стандартный обработчик запроса конечной точки), Class Device request handler (классовый обработчик запроса устройства) и т. п. То, как Вы проинализируете пакет setup, зависит только от Ваших предпочтений. Кто-то еще может захотеть сначала анализировать bRequest и потом определить тип запроса и его получателя на основании каждого запроса.
Стандартные запросы являются общими для всех устройств USB и подробно рассмотрены на последующих страницах. Классовые запросы являются общими для классов драйверов. Например, все устройства, относящиеся к классу HID, будут иметь единый набор запросов, специфичных для класса. Они будут отличаться от запросов устройства, относящегося к классу communication или относящегося к классу mass storage.
И наконец – запросы, определенные вендором (производителем). Это запросы, которые Вы как разработчик устройства USB, ножете назначить сами. Эти запросы отличаются от устройства к устройству (что нормально), но это все делается исключительно под Вашу реализацию алгоритма работы устройства.
Общие запросы могут быть перенаправлены на различных получателей, и в зависимости от конкретного получателя выполнять разные функции. Например, стандартный запрос GetStatus может быть направлен на устройство, интерфейс или конечную точку. Когда он направлен на устройство, он возвращает флаги, показывающие статус удаленного пробуждения (remote wakeup), и является ли устройство самопитаемым. Однако тот же запрос, направленный к интерфейсу, всегда вернет 0, или если запрос будет направлен на конечную точку, то он вернет состояние флага halt (флаг останова) для конечной точки.
Поля wValue и wIndex позволяют передавать параметры вместе с запросом, а поле wLength используется для указания количества байт, которые должны быть переданы на фазе данных.
Примечание переводчика: иногда поля wValue и wIndex применяют для передачи данных без участия специальной фазы данных (в поле wLength указывают 0), в этом случае можно передать не больше 4 байт. Пример такого использования таких управляющих запросов для передачи данных в обе стороны можно найти в примере hid-custom-rq из библиотеки V-USB (http://ru.wikipedia.org/wiki/V-USB), или в статье «V-USB и libusb: обмен с устройством USB HID с помощью управляющих сообщений (USB control messages)»
продолжение следует...
Часть 1 Все о USB , Программирование USB интерфейса и работа с USB периферии для программистов
Часть 2 Цоколевки разъема и кабеля - Все о USB , Программирование
Часть 3 Глава 4: Типы конечных точек (Endpoint Types ) - Все
Часть 4 Глава 5: Дескрипторы USB - Все о USB , Программирование
Часть 5 Глава 7 : обычный (Generic) драйвер USB - Все о
Часть 6 Термины - Все о USB , Программирование USB интерфейса и
Комментарии
Оставить комментарий
Операционные системы и системное программировние
Термины: Операционные системы и системное программировние