Дескрипторы
Известно, что к проектированию архитектуры шины USB подходили весьма основательно. Хотели создать архитектуру, которая сможет удовлетворить потребности самых сложных периферийных устройств, широкого спектра применения. Для этого придумали достаточно сложную структуру иерархических данных, называемую набор дескрипторов. В этой структуре, формат которой строго регламентируется стандартом, должна храниться вся информация, с помощью которой хост может автоматически конфигурироваться и начинать нормальную работу с USB устройством. Именно набором дескрипторов USB устройства обменивается с хостом во время процесса энумерации. Имеется 4 основных типа дескрипторов: дескриптор устройства, дескриптор конфигурации, дескриптор интерфейса и дескриптор конечной точки. Все эти виды дескрипторов должны обязательно присутствовать в USB устройстве. Рисунок 3 поясняет сказанное.
Рисунок 3 |
Конечные точки объединяются в интерфейс. Каждому интерфейсу соответствует драйвер операционной системы (ОС) хоста. Некоторые устройства могут иметь несколько интерфейсов, которые могут функционировать одновременно. Телефонный аппарат VOIP может иметь интерфейс клавиатуры и аудио интерфейс, тогда ОС хоста будет использовать 2 различных драйвера, для каждого интерфейса. А прикладная программа, будет взаимодействовать с этими драйверами для функционирования. Несколько интерфейсов, могут объединяться в конфигурацию. У USB устройства может быть несколько конфигураций, но не может быть активными несколько конфигураций одновременно, возможно переключение между конфигурациями. В наших примерах не будем использовать USB устройства с несколькими дескрипторами конфигураций и несколькими дескрипторами интерфейсов.
Кроме базовых дескрипторов, которые являются основными, для создания работоспособного устройства, имеются и прочие дескрипторы. Об этих дескрипторах упомянем после.
С начала для сторонников Linux, потом для Windows. Что представляют дескрипторы мыши USB, можно увидеть, воспользовавшись утилитой lsusb для Linux. Эта команда не в точности выда.т структуру дескрипторов USB устройства, но очень близкую. Введ.м команду и перенаправим е. вывод в текстовый файл, а затем файл откроем в любом текстовом редакторе.
alex@big:~$ sudo lsusb -d 0458:003a -v > dsc.txt
|
Здесь в качестве параметра указан идентификатор устройства, дескрипторы которого требуется вывести и дополнительные ключи. Ищем и открываем файл dsc.txt. Как узнать идентификатор мыши PC, писалось выше.
Посмотрим на содержимое файла dsc.txt. Легко распознать секции с дескрипторами устройства, конфигурации, интерфейса и конечной точки. В названиях полей дескрипторов имеются префиксы, соответственные типу данных.
|
Bus 003 Device 002: ID 0458:003a KYE Systems Corp. (Mouse Systems)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0458 KYE Systems Corp. (Mouse Systems)
idProduct 0x003a
bcdDevice 1.00
iManufacturer 1 Genius
iProduct 2 Optical Mouse
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 4 HID-compliant MOUSE
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 2 Mouse
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 62
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0004 1x 4 bytes
bInterval 10
Device Status: 0x0000
(Bus Powered)
|
Начнем с описания полей дескриптора устройства.
Поле |
Размер |
Описание |
bLength |
1 |
размер дескриптора в байтах |
bDescriptorType |
1 |
тип дескриптора |
bcdUSB |
2 |
номер спецификации USB, которой удовлетворяет устройство, в двоично-десятичном формате |
bMaxPacketSize |
1 |
максимальный размер пакета для конечной точки 0, из ряда 8,16,32,64 |
idVendor |
2 |
код разработчика |
idProduct |
2 |
код разработки |
bcdDevice |
2 |
код версии разработки, в двоично-десятичном виде |
iManufacturer |
1 |
индекс текстовой строки производителя |
iProduct |
1 |
индекс текстовой строки изделия |
iSerial |
1 |
индекс текстовой строки серийного номера |
bNumConfigurations |
1 |
количество возможных конфигураций |
Поле bMaxPacketSize зада.т размер максимального пакета конечной точки управления. Конечная точка управления используется для приема команд от хоста. Эта конечная точка не имеет дескриптора, только задается размер ее буфера. Дескрипторы могут содержать не только информацию в двоичном коде, а так же и текст. Эта информация не обязательна для работы USB устройства, но весьма ценна для человеческого восприятия. Для передачи этой информации служат строковые дескрипторы. Дескриптор строки состоит из 2 байтных символов UNICODE-16 v1. Такая кодировка используется в Windows. Структура строковых дескрипторов не описана в дампе вывода, lsusb извлекла текст по умолчанию и подставила в отчет. Поля с индексами, указывают на номер строкового дескриптора в пуле строковых дескрипторов. Если в индексном поле задан 0, то считается, что строковый дескриптор не задан. Из дампа информации выведенной lsusb видно, что iSerial не задано, а описатель iProduct имеет индекс 2.
Поля: bDeviceClass, bDeviceSubClass, bDeviceProtocol применяются в USB устройствах, относящихся к стандартизованным классам устройств. Ранее уже сообщалось о существовании унифицированных классах устройств, существующих в рамках стандарта USB. Классы устройств – это надстройка над базовым USB. По аналогии, протокол прикладного уровня HTTP – это надстройка над TCP/IP. Рассматриваемая мышь относится к классу устройств HID. Но это отдельная большая тема. Важно знать, что совсем не обязательно разбираться в протоколах типа HID, для того чтобы создавать устройства на микроконтроллерах с USB.
Далее идет дескриптор конфигурации.
Поле |
Размер |
Описание |
wTotalLength |
1 |
полная длина возвращаемых данных |
bNumInterfaces |
1 |
количество интерфейсов |
bConfigurationValue |
1 |
условный номер конфигурации |
iConfiguration |
1 |
индекс строкового дескриптора к конфигурации |
bmAttributes |
1 |
атрибуты конфигурации |
bMaxPower |
1 |
|
максимальный ток потребления в единицах по 2 mA
Поле bMaxPower задает максимальный ток, потребляемый USB устройством. Задается в единицах кратных 2 миллиамперам. В дампе lsusb этот параметр уже перевед.н в миллиамперы. Поле bmAttributes – набор битов, способ одним байтом задать несколько параметров. Этим полем задаются энергетические характеристики устройства. Поэтому сделаем некоторое введение.
Все USB устройства делятся на 3 класса по потребляемой энергии: питаемые от шины, питаемые от шины с высоким потреблением энергии и имеющие собственный источник энергии. Напомним, что USB устройства подключаемые к шине USB, могут получать энергию по самой шине. Те что потребляют меньше 100 миллиампер, относятся к классу с низким потреблением (Low power ). А USB устройства потребляющие до 500 миллиампер от самой шины, относятся к мощным (High power). Третья категория это те, что имеют собственный источник (Self powered). Имеющие собственный источник питания, могут потреблять дополнительно и от шины, но не боле 100 миллиампер.
Если установлен бит 6 поля bmAttribute, то это указывает, что USB устройство имеет собственный источник питания. Бит 5, что USB устройство может являться источником сигнала пробуждения, выводящим вышестоящий хаб из состояния низкого потребления. Теперь ясно, почему моя мышь может разбудить компьютер. Остальные биты зарезервированы.
В дескрипторе интерфейса, пока только интересным являются поля bNumEndpoints и поле iInterface. Из названия ясно, что одно поле зада.т количество конечных точек в интерфейсе, не считая управляющей конечной точки. Другое поле - индекс строкового дескриптора, указывающий на строковый дескриптор интерфейса. Поля относящиеся к секции HID Device Descriptor, рассматривать не будем.
Последним идет дескриптор единственной конечной точки.
Поле |
Размер |
Описание |
bEndpointAddress |
1 |
адрес конечной точки |
bmAttributes |
1 |
битовое поле атрибутов |
wMaxPacketSize |
1 |
максимальный размер пакета |
bInterval |
1 |
интервал опроса в миллисекундах |
Адрес конечной точки состоит из 2-х частей, номер и направление. Для номера выделены биты 0..3 , а для направления предназначен бит 7. Если этот бит установлен, то конечная точка ввода. Остальные биты зарезервированы. Всего можно адресовать до 30 точек, 15 на ввод и 15 на вывод. Нулевой адрес зарезервирован для точки управления. Из дампа вывода видно, что у мыши конечная точка типа ввода, посылает данные на хост и имеет номер 1.
Поле bmAttributes , биты 0..1 задают тип точки: 0 – управления, 1 – изохронной передачи, 2 – массовой передачи, 3 – передачи по прерыванию. Биты 2..5 имеют смысл только для изохронных типов конечных точек. Биты 2..3 задают тип синхронизации для изохронной конечной точки: 0 – нет синхронизации, 1 – асинхронная, 2 – адаптивная, 3 – синхронная. Биты 4..5 задают тип использования изохронной конечной точки: 0 – для данных , 1 – обратная связь, 2 – данные с предоставлением неявной обратной связи, 3 – зарезервировано. Смысл этих параметров относится к изохронным передачам, которые не будем рассматривать подробно. Поле wMaxPacketSize , зада.т максимальный размер пакета, который способна принять точка. Мышь переда.т хосту пакеты данных по 4 байта. Поле bInterval зада.т максимально возможную задержку опроса, для конечных точек передач по прерыванию. При поступлении запроса от хоста на передачу данных, данные будут переданы с возможной задержкой не более чем значение в bInterval. Для изохронных точек всегда 1. Для остальных не имеет значения. Мышь опрашивается с частотой 10 миллисекунд.
В ОС Windows дамп вывода программы UsbTreeView для мыши USB, приведен ниже, нет только информации специфичной для Windows. По моему мнению, информация более удобная для восприятия. Строковые дескрипторы показываются отдельно.
|
------------------ Device Descriptor ------------------
bLength : 0x12 (18 bytes)
bDescriptorType : 0x01 (Device Descriptor)
bcdUSB : 0x110 (USB Version 1.10)
bDeviceClass : 0x00 (defined by the interface descriptors)
bDeviceSubClass : 0x00
bDeviceProtocol : 0x00
bMaxPacketSize0 : 0x08 (8 bytes)
idVendor : 0x0458 (KYE Systems Corp.)
idProduct : 0x003A
bcdDevice : 0x100
iManufacturer : 0x01
Language 0x0409 : "Genius"
iProduct : 0x02
Language 0x0409 : "Optical Mouse"
iSerialNumber : 0x00
bNumConfigurations : 0x01
------------------ String Descriptors -----------------
------ String Descriptor 0 ------
bLength : 0x04 (4 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language ID[0] : 0x0409 (English - United States)
------ String Descriptor 1 ------
bLength : 0x0E (14 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "Genius"
------ String Descriptor 2 ------
bLength : 0x1C (28 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "Optical Mouse"
------ String Descriptor 4 ------
bLength : 0x28 (40 bytes)
bDescriptorType : 0x03 (String Descriptor)
Language 0x0409 : "HID-compliant MOUSE"
-------------- Configuration Descriptor ---------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x02 (Configuration Descriptor)
wTotalLength : 0x0022 (34 bytes)
bNumInterfaces : 0x01
bConfigurationValue : 0x01
iConfiguration : 0x04
Language 0x0409 : "HID-compliant MOUSE"
bmAttributes : 0xA0
D7: Reserved, set 1 : 0x01
D6: Self Powered : 0x00 (no)
D5: Remote Wakeup : 0x01 (yes)
D4..0: Reserved, set 0 : 0x00
MaxPower : 0x32 (100 mA)
---------------- Interface Descriptor -----------------
bLength : 0x09 (9 bytes)
bDescriptorType : 0x04 (Interface Descriptor)
bInterfaceNumber : 0x00
bAlternateSetting : 0x00
bNumEndpoints : 0x01 (1 Endpoints)
bInterfaceClass : 0x03 (HID - Human Interface Device)
bInterfaceSubClass : 0x01 (Boot Interface)
bInterfaceProtocol : 0x02 (Mouse)
iInterface : 0x00
----------------- Endpoint Descriptor -----------------
bLength : 0x07 (7 bytes)
bDescriptorType : 0x05 (Endpoint Descriptor)
bEndpointAddress : 0x81 (Direction=IN EndpointID=1)
bmAttributes : 0x03 (TransferType=Interrupt)
wMaxPacketSize : 0x04
bInterval : 0x0A (10 ms)
|
Здесь все те же дескрипторы, только в ином виде. Без труда можно разобраться, с учетом информации приведенной выше для Linux.
Даже такое поверхностное знание организации USB, позволяет решать некоторые проблемы. В ОС Windows, сведения об устройствах USB, которые подключались, и с которыми работала система, записываются в системный реестр и там хранятся. При подключении устройства, которое уже подключалось, информация о конфигурации берется именно оттуда. Иногда происходит сбой и USB устройство система не видит. У меня так бывало с принтерами, сканерами, конвертерами USB<=>RS-232. Лучше утилитой типа USBview, посмотреть подключенные устройства и дескрипторы проблемного устройства. Часто, даже беглого взгляда достаточно, чтобы понять, что устройство неверно сконфигурировано. В большинстве случаев, для решения проблемы требуется удалить испорченные записи об устройстве в реестре. Создайте командный файл следующего содержания:
|
SET DEVMGR_SHOW_NONPRESENT_DEVICES=1
MMC DEVMGMT.MSC
|
Этот набор команд файла, запустит диспетчер устройств и установит значение переменной среды. Далее установить галочку в меню «Вид -> Показать скрытые устройства ». Записи о драйверах скрытых устройств будут приглуш.нного цвета, удалите ненужную запись и вставьте штекер USB проблемного устройства. Проблемное устройство будет сконфигурировано с белого листа. Те же задачи, но более комфортно можно решить с программой USBDeview от Nir Sofer.
.
|