Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Агуров П.В. -> "Интерфейсы USB. Практика использования и программирования" -> 45

Интерфейсы USB. Практика использования и программирования - Агуров П.В.

Агуров П.В. Интерфейсы USB. Практика использования и программирования — СПб.: БХВ-Петербург, 2004. — 576 c.
ISBN 5-94157-202-6
Скачать (прямая ссылка): interface2004.djvu
Предыдущая << 1 .. 39 40 41 42 43 44 < 45 > 46 47 48 49 50 51 .. 166 >> Следующая

1 bDescriptorType 1 Тип дескриптора (usb_string_descriptor_type)
2 wLANGID[0] 2 Идентификатор языка
N wLANGID[x] 2 Идентификатор языка
Специфические дескрипторы
Специфические дескрипторы (Class-Specific Descriptor) могут использоваться в устройствах определенных классов. Например, в разд. 5.1.2 мы будем описывать дескрипторы, специфические для хабов.
Порядок получения дескрипторов
В процессе нумерации (см. разд. 10.2.2) хост с помощью управляющих посылок (см. разд. 3.3) запрашивает дескрипторы от устройства в такой последовательности:
? дескриптор устройства;
? дескрипторы конфигураций;
? дескрипторы интерфейсов для конфигурации;
? дескрипторы интерфейсов всех конечных точек.
118
Часть II. Внутренняя организация USB
Реально при запросе дескриптора конфигурации устройство сразу возвращает последовательность "вложенных" дескрипторов:
? дескриптор конфигурации-1;
• дескриптор интерфейса-1;
О дескриптор конечной точки-1 для интерфейса-1; О дескриптор конечной точки-2 для интерфейса-1; О ..............
• дескриптор интерфейса-2;
О дескриптор конечной точки-1 для интерфейса-2;
? дескриптор конфигурации-2.
Общая длина возвращаемых данных заранее не известна. Для определения общей длины возвращаемого списка дескрипторов служит поле wTotalLength. Чтобы получить весь список дескрипторов, нужно запросить первые 8 байт дескриптора конфигурации, запомнить значение поля wTotalLength, а затем использовать это значение в качестве параметра при повторной подаче запроса. Важно понимать, что такой алгоритм действий выполняется внутри USB-драйвера, а со стороны пользовательской программы получение списка дескрипторов выглядит несколько проще (листинг 4.10).
Листинг 4.10. Получение списка дескрипторов конфигурации
// конфигурационный пакет запроса TSetupPacket = packed record
bmRequest : UCHAR;
bRequest : UCHAR;
wValue : Array [1..2] of UCHAR;
windex : Array [1..2] of UCHAR;
wLength : Array [1..2] of UCHAR; End; /
Il структура запроса дескриптора TDescriptorRequest = packed record
Connectionlndex : ULONG;
SetupPacket : TSetupPacket;
Data : Array [1..2048] of Byte;
End;
Глава 4. Внутренняя организация устройства
119
procedure TForml.ShowDeviceDetail(hRoot : THandle; iPort : Integer); Il переменные для выполнения DeviceloControl Var Success : LongBool;
Packet : TDescriptorRequest;
BytesReturned : Cardinal;
begin
Il Получение стандартного дескриптора устройства ZeroMemory(OPacket, SizeOf(Packet));
Packet.Connectionlndex Packet.SetupPacket.bmRequest Packet.SetupPacket.bRequest Packet.SetupPacket.wValue [2] Packet.SetupPacket.wLength[2]
= iPort+1; = $80;
= USB_REQUEST_GET_DESCRIPTOR; = USB_DEVICE_DESCRIPTOR_TYPE; = 1; Il Использовать буфер 2 Кбайт
II IOCTL_USB_GET__DESCRIPTOR_FROM__NODE_CONNECTION Success:= DeviceloControl(hRoot, GetUSBCtlCode(5),
SPacket, sizeof(Packet),
SPacket, sizeof(Packet),
BytesReturned, nil ) ;
If not(Success) then begin
Log(Format (' Ошибка получения информации об устройстве %s', [ SysErrorMessage(GetLastError())]));
Exit; End;
11 отображение дескриптора устройства DisplayDescriptorlnfо(Packet. Data);
11 Получение дескрипторов конфигурации ZeroMemory(SPacket, SizeOf(Packet)) ;
Packet.Connectionlndex Packet.SetupPacket.bmRequest Packet.SetupPacket.bRequest Packet.SetupPacket.wValue [2] Packet.SetupPacket.wLength[2]
= iPort+1; = $80;
= USB_REQUEST_GET_DESCRIPTOR;
= USB_CONFIGURATION_DESCRIPTORJTYPE;
= 1; // Использовать буфер 2 Кбайт
120
Часть II. Внутренняя организация USB
Il IOCTL USB GET DESCRIPTOR BROM NODE CONNECTION
Success:= DeviceloControl(hRoot, GetUSBCtlCode(5),
@Packet, sizeof(Packet), @Packet, sizeof(Packet), BytesReturned, nil ) ;
If not(Success) then begin Log (Format (' Ошибка no'
Ошибка получения информации об устройстве %s', [ SysErrorMessage(GetLastError())]));
Exit;
End;
Il отображение информации о дескрипторах конфигурации DisplayDescriptorlnfо(Packet. Data); End;
Описание функции DeviceloControl можно найти в справочной части книги (см. разд. 16.9). В нашем примере ключевыми параметрами этой функции являются:
? hRoot — дескриптор порта, к которому подключено устройство;
? Getusbcticode (5) — код IOCTL-функции (см. разд. 9.3.5);
? Packet — Структура ТИПа TDescriptorRequest.
Подробности обращения к USB-драйверу мы будем обсуждать в главе 7, а внутреннюю организацию самих драйверов — в главе 9.
Как видно из листинга, в результате выполнения запроса возвращается буфер данных Packet.Data. Для разбора и отображения этого буфера можно
ИСПОЛЬЗОВаТЬ Процедуру DisplayDescriptorlnfо, КОД Которой ПОКазаН В
листинге 4.11.
procedure TForml.DisplayDescriptorlnfо(Data : Array of byte); var iData : Integer; lenDescr, typDescr : Byte; PData : Pointer; begin
Il Проходим по массиву дескрипторов
Il Первый байт - размер дескриптора в байтах
// Второй байт - тип дескриптора
iData:= 0;
І л*і||гмнг 4.11 *РюШр спискаЗШкрипторре
гпава 4. Внутренняя организация устройства
121
Repeat lenDescr typDescr PData
Предыдущая << 1 .. 39 40 41 42 43 44 < 45 > 46 47 48 49 50 51 .. 166 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100