Оглавление Введение 1
Для кого эта книга 1
Что вы найдете в книге 2
Программные требования 2
Аппаратные требования 2
О программном коде 3
Краткое описание глав 3
Обозначения 5
Благодарности 6
Обратная связь 6
ЧАСТЬ I. ОБЩИЕ СВЕДЕНИЯ О USB 7
Глава 1. Спецификация USB 9
1.1. Что такое USB и зачем это надо 9
1.1.1. Общая архитектура USB 11
1.1.2. Физическая и логическая архитектура USB 11
1.1.3. Составляющие USB 13
1.1.4. Свойства USB-устройств 14
1.1.5. Принципы передачи данных 15
1.1.6. Механизм прерываний 15
1.1.7. Режимы передачи данных 15
1.1.8. Логические уровни обмена данными 16
1.1.8.1. Уровень клиентского ПО 17
1.1.8.2. Уровень системного драйвера USB 17
1.1.8.3. Уровень хост-контроллера интерфейса 19
1.1.8.4. Уровень шины периферийного USB-устройства 19
1.1.8.5. Уровень логического USB-устройства 19
1.1.8.6. Функциональный уровень USB-устройства 19
1.1.9. Передача данных по уровням 20
1.1.10. Типы передач данных 21
1.1.11. Кадры 24
1.1.12. Конечные точки 25
1.1.13. Каналы 26
1.1.14. Пакеты 27
1.1.14.1. Формат маркер-пакетов IN, OUT, SETUP и PING 29
1.1.14.2. Формат пакета SOF 30
1.1.14.3. Формат пакета данных 30
1.1.14.4. Формат пакета подтверждения 31
1.1.14.5. Формат пакета SPLIT 31
1.1.15. Контрольная сумма 32
1.1.15.1. Алгоритм вычисления CRC 32
1.1.15.2. Программное вычисление CRC 34
1.1.16. Транзакции 37
1.1.16.1. Типы транзакций 37
1.1.16.2. Подтверждение транзакций и управление потоком 38
1.1.16.3. Протоколы транзакций 40
1.2. Запросы к USB-устройствам 42
1.2.1. Конфигурационный пакет 42
1.2.2. Стандартные запросы к USB-устройствам 46
1.2.2.1. Получение состояния GET_STATUS 46
1.2.2.2. Сброс свойства CLEAR_FEATURE 47
1.2.2.3. Разрешение свойства SET_FEATURE 47
1.2.2.4. Задание адреса на шине SET_ADDRESS 48
1.2.2.5. Получение дескриптора GET_DESCRIPTOR 48
1.2.2.6. Передача дескриптора SET_DESCRIPTOR 49
1.2.2.7. Получение кода конфигурации GET_CONFIGURATION 49
1.2.2.8. Задание кода конфигурации SET_CONFIGURATION 50
1.2.2.9. Получение кода настройки интерфейса GET_INTERFACE 50
1.2.2.10. Задание кода настройки интерфейса SET_INTERFACE 50
1.2.2.11. Задание номера кадра синхронизации SYNC_FRAME 51
1.2.2.12. Обработка стандартных запросов 51
1.2.3. Дескриптор устройства 52
1.2.3.1. Дескриптор устройства 52
1.2.3.2. Уточняющий дескриптор устройства 55
1.2.3.3. Дескриптор конфигурации 56
1.2.3.4. Дескриптор интерфейса 59
1.2.3.5. Дескриптор конечной точки 60
1.2.3.6 Дескриптор строки 63
1.2.3.7. Специфические дескрипторы 64
1.2.3.8. Порядок получения дескрипторов 65
1.3. Система Plug and Play (PnP) 69
1.3.1. Конфигурирование USB-устройств 70
1.3.2. Нумерация USB-устройств 70
1.3.3. PnP-идентификаторы USB-устройств 72
1.3.4. Символьные имена устройств 73
1.4. Модель WDM 74
Глава 2. Программирование на языке С для микроконтроллера 78
2.1. Общие сведения о языке С для микроконтроллеров 78
2.2. Использование стандартных библиотек 80
2.3. Программирование для AT89C5131 80
2.3.1. Файл инициализации 81
2.3.2. Структуры дескрипторов 83
2.3.3. Структура проекта 85
Глава 3. Инструменты 87
3.1. Программаторы 87
3.1.1. Программатор Flip 87
3.1.2. Программатор ER-Tronik 91
3.2. Инструменты создания драйверов 94
3.2.1. NuMega Driver Studio 94
3.2.2. Jungo WinDriver 94
3.2.3. Jungo KernelDriver 94
3.3. Средства Microsoft Visual Studio 94
3.3.1. Depends (Dependency Walker) 95
3.3.2. Error Lookup 95
3.3.3. GuidGen 95
3.4. Средства Microsoft DDK 96
3.4.1. DeviceTree 97
3.4.2. DevCon 97
3.4.2.1. Ключ classes 98
3.4.2.2. Ключ driverfiles 98
3.4.2.3. Ключ hwids 100
3.4.2.4. Ключ rescan 101
3.4.2.5. Ключ stack 101
3.4.2.6. Ключ status 102
3.4.3. ChkInf и GenInf 103
3.5. Средства CompuWare Corporation 103
3.5.1. Monitor 103
3.5.2. SymLink 104
3.5.3. EzDriverInstaller 104
3.5.4. WdmSniff 105
3.6. Средства SysInternals 106
3.6.1. WinObj 106
3.7. Средства USB Forum 106
3.7.1. HID Descriptor Tool 106
3.8. USB Command Verifier 109
3.9. Средства HDD Software 111
3.10. Средства Sourceforge 111
3.11. Программа мониторинга Bus Hound 112
Глава 4. Принципы использования функций Win32 в .NET 114
4.1. Общие сведения 114
4.2. Импорт функций Win32 115
4.3. Структуры 116
4.3.1. Атрибут StructLayout 117
4.3.2. Атрибут MarshalAs 118
4.4. Прямой доступ к данным 120
4.5. Обработка сообщений Windows 121
4.6. Общие сведения о WMI 122
4.7. Интернет-ресурсы к этой главе 124
ЧАСТЬ II. КЛАССЫ USB 125
Глава 5. Класс CDC 127
5.1. Методы преобразования интерфейсов USB/RS-232 127
5.2. Общие сведения об интерфейсе RS-232 128
5.2.1. Линии обмена 129
5.2.1.1. Передаваемые данные (ВА/TxD/TD) 130
5.2.1.2. Принимаемые данные (ВВ/RxD/RD) 130
5.2.1.3. Запрос передачи (СА/RTS) 130
5.2.1.4. Готовность к передаче (CB/CTS) 131
5.2.1.5. Готовность DCE (СС/DSR) 132
5.2.1.6. Готовность DTE (CD/DTR) 132
5.2.1.7. Индикатор вызова (СЕ/RI) 132
5.2.1.8. Обнаружение несущей (CF/DCD) 132
5.2.1.9. Готовность к приему (CJ) 133
5.3. Спецификация CDC 133
5.3.1. Стандартные дескрипторы 133
5.3.2. Функциональные дескрипторы 135
5.3.2.1. Заголовочный функциональный дескриптор 136
5.3.2.2. Дескриптор режима команд 137
5.3.2.3. Дескриптор абстрактного устройства 138
5.3.2.4. Дескриптор группирования 138
5.3.3. Специальные запросы 139
5.3.3.1. Запрос SET_LINE_CODING 139
5.3.3.2. Запрос GET_LINE_CODING 140
5.3.3.3. Запрос SET_CONTROL_LINE_STATE 140
5.3.3.4. Запрос SEND_BREAK 141
5.3.4. Нотификации 141
5.3.4.1. Нотификация RING_DETECT 141
5.3.4.2. Нотификация SERIAL_STATE 141
5.4. Поддержка CDC в Windows 142
5.4.1. Обзор функций Windows для работы с последовательными портами 142
5.4.1.1. Основные операции с портом 142
5.4.1.2. Функции настройки порта 143
5.4.1.3. Специальная настройка порта 143
5.4.1.4. Получение состояния линий модема 144
5.4.1.5. Работа с CDC на платформе .NET 144
5.4.2. Соответствие функций Windows и USB-запросов 144
Глава 6. Класс HID 146
6.1. Спецификация HID-устройств 146
6.2. Порядок обмена данными с HID-устройством 148
6.3. Установка драйвера HID-устройства 149
6.4. Идентификация HID-устройства 149
6.4.1. Идентификация загрузочных устройств 150
6.4.2. Дескриптор конфигурации HID-устройства 150
6.4.3. HID-дескриптор 151
6.4.4. Дескриптор репорта 153
6.5. Структура дескриптора репорта 153
6.5.1. Элементы репорта 154
6.5.1.1. Элементы короткого типа 154
6.5.1.2. Элементы длинного типа 154
6.5.2. Типы элементов репорта 155
6.5.2.1. Основные элементы 155
6.5.2.2. Глобальные элементы 158
6.5.2.3. Локальные элементы 161
6.5.3. Примеры дескрипторов 162
6.6. Запросы к HID-устройству 165
6.6.1. Запрос GET_REPORT 166
6.6.2. Запрос SET_REPORT 167
6.6.3. Запрос GET_IDLE 167
6.6.4. Запрос SET_IDLE 168
6.6.5. Запрос GET_PROTOCOL 168
6.6.6. Запрос SET_PROTOCOL 169
6.7. Инструменты 169
6.8. Драйверы для HID-устройств в Windows 169
Глава 7. Другие классы USB 179
ЧАСТЬ III. ПРАКТИКА ПРОГРАММИРОВАНИЯ USB 181
Глава 8. Создание USB-устройства на основе AT89C5131 183
8.1. Общая информация об AT89C5131 183
8.2. Структурная схема AT89C5131 185
8.3. USB-регистры AT89C5131 187
8.3.1. Регистр USBCON 187
8.3.2. Регистр USBADDR 189
8.3.3. Регистр USBINT 190
8.3.4. Регистр USBIEN 191
8.3.5. Регистр UEPNUM 192
8.3.6. Регистр UEPCONX 193
8.3.7. Регистр UEPSTAX 195
8.3.8. Регистр UEPRST 197
8.3.9. Регистр UEPINT 198
8.3.10. Регистр UEPIEN 199
8.3.11. Регистр UEPDATX 200
8.3.12. Регистр UBYCTLX 201
8.3.13. Регистр UFNUML 201
8.3.14. Регистр UFNUMH 201
8.4. Cхемотехника AT89C5131 202
8.5. Базовый проект для AT89C5131 204
8.5.1. Первая версия программы для AT89C5131 204
8.5.2. Добавляем строковые дескрипторы 226
8.5.3. Добавление конечных точек 231
8.6. Загрузка программы 235
Глава 9. Реализация класса CDC 236
9.1. Реализация CDC 236
9.2. Дескрипторы устройства 237
9.2.1. Инициализация конечных точек 240
9.2.2. Обработка CDC-запросов 241
9.2.3. Конфигурирование RS-порта и CDC-линии 243
9.2.4. Прием и передача данных 244
9.3. Установка драйвера 247
9.4. Программирование обмена данными с CDC-устройством на языке Delphi 249
9.5. Программирование обмена с CDC-устройством на языке C# 279
9.5.1. Использование компонента MSCOMM 279
9.5.2. Использование функций Win32 283
9.6. Проблемы CDC 289
Глава 10. Реализация класса HID 290
10.1. Реализация HID на AT89C5131 290
10.2. Передача нескольких байтов 296
10.3. Feature-репорты 298
10.4. Передача данных от хоста (SET_REPORT) 300
10.5. Установка HID-устройства 301
10.6. Обмен данными с HID-устройством 301
10.6.1. Получение имени HID-устройства 302
10.6.2. Получение атрибутов устройства и чтение репортов 305
10.6.3. Передача данных от хоста к HID-устройству 311
10.7. Примеры HID-устройств 312
10.7.1. Реализация устройства "мышь" 312
10.7.2. Реализация устройства "клавиатура" 313
10.8. Использование HID-протокола 316
10.8.1. Интерпретация данных 318
10.8.2. Коллекции 320
10.8.3. Массивы и кнопки 326
10.9. HID-устройство с несколькими репортами 329
Глава 11. Специальные функции Windows 332
11.1. Функции Setup API 332
11.1.1. Перечисление USB-устройств 332
11.1.2. Получение состояния USB-устройства 342
11.2. Перечисление USB-устройств с помощью WMI 345
11.3. Специальные функции Windows XP 347
11.3.1. HidD_GetInputReport — чтение HID-репортов 347
11.3.2. Получение данных Raw Input 348
11.4. Функции DirectX 357
11.5. Диалог добавления нового оборудования 363
11.6. Работа с символьными именами устройств 364
11.7. Безопасное извлечение флэш-дисков 368
11.8. Обнаружение добавления и удаления устройств 374
11.9. Интернет-ресурсы 378
Глава 12. Разработка драйвера 379
12.1. Основные процедуры драйвера WDM 379
12.1.1. Процедура DriverEntry 379
12.1.2. Процедура AddDevice 382
12.1.3. Процедура Unload 384
12.1.4. Рабочие процедуры драйвера 386
12.1.4.1. Заголовок пакета 386
12.1.4.2. Ячейки стека ввода/вывода 387
12.4.1.3. Рабочие процедуры драйвера 388
12.1.5. Обслуживание запросов IOCTL 393
12.2. Загрузка драйвера и обращение к процедурам драйвера 399
12.2.1. Процедура работы с драйвером 399
12.2.2. Регистрация драйвера 401
12.2.2.1. Регистрация с помощью SCM-менеджера 401
12.2.2.2. Параметры драйвера в реестре 406
12.2.3. Обращение к рабочим процедурам 408
12.2.4. Хранение драйвера внутри исполняемого файла 409
12.3. Создание драйвера с помощью Driver Studio 411
12.3.1. Несколько слов о библиотеке Driver Studio 413
12.3.1.1. Класс KDriver 413
12.3.1.2. Класс KDevice 413
12.3.1.3. Класс KIrp 414
12.3.1.4. Класс KRegistryKey 414
12.3.1.5. Класс KLowerDevice 414
12.3.1.6. Классы USB 416
12.3.2. Другие классы Driver Studio 417
12.3.3. Создание шаблона драйвера с помощью Driver Studio 417
12.3.3.1. Шаг 1. Задание имени и пути проекта 418
12.3.3.2. Шаг 2. Выбор архитектуры драйвера 418
12.3.3.3. Шаг 3. Выбор шины 418
12.3.3.4. Шаг 4. Задание набора конечных точек 420
12.3.3.5. Шаг 5. Задание имени класса и файла 421
12.3.3.6. Шаг 6. Выбор функций драйвера 421
12.3.3.7. Шаг 7. Выбор способа обработки запросов 423
12.3.3.8. Шаг 8. Создание сохраняемых параметров драйвера 424
12.3.3.9. Шаг 9. Свойства драйвера 425
12.3.3.10. Шаг 10. Задание кодов IOCTL 427
12.3.3.11. Шаг 11. Дополнительные настройки 427
12.3.4. Доработка шаблона драйвера 429
12.3.5. Базовые методы класса устройства 429
12.3.6. Реализация чтения данных 433
12.3.7. Установка драйвера 434
12.3.8. Программа чтения данных 435
12.3.9. Чтение данных с конечных точек других типов 445
12.3.10. "Чистый" драйвер USB-устройства 446
ЧАСТЬ IV. СПРАВОЧНИК 465
Глава 13. Формат INF-файла 467
13.1. Структура INF-файла 467
13.1.1. Секция Version 468
13.1.2. Секция Manufacturer 470
13.1.3. Секция DestinationDirs 472
13.1.3.1. Ключ DefaultDescDir 472
13.1.3.2. Ключи file-list-section 472
13.1.3.3. Ключ dirid 473
13.1.3.4. Ключ subdir 474
13.1.4. Секция описания модели 474
13.1.5. Секция xxx.AddReg и xxx.DelReg 475
13.1.6. Секция xxx.LogConfig 477
13.1.7. Секция xxx.CopyFiles 477
13.1.8. Секция Strings 479
13.1.9. Связи секций 479
13.2. Создание и тестирование INF-файлов 480
13.3. Установка устройств с помощью INF-файла 482
13.4. Ветки реестра для USB 482
Глава 14. Базовые функции Windows 484
14.1. Функции CreateFile и CloseHandle: открытие и закрытие объекта 484
14.1.1. Дополнительные сведения 485
14.1.2. Возвращаемое значение 486
14.1.3. Пример вызова 486
14.2. Функция ReadFile: чтение данных 488
14.2.1. Дополнительные сведения 489
14.2.2. Возвращаемое значение 490
14.2.3. Пример вызова 490
14.3. Функция WriteFile: передача данных 491
14.3.1. Дополнительные сведения 492
14.3.2. Возвращаемое значение 492
14.3.3. Пример вызова 493
14.4. Функция ReadFileEx: APC-чтение данных 494
14.4.1. Возвращаемое значение 495
14.4.2. Дополнительные сведения 495
14.4.3. Пример вызова 496
14.5. Функция WriteFileEx: APC-передача данных 496
14.5.1. Возвращаемое значение 497
14.5.2. Пример вызова 497
14.6. Функция WaitForSingleObject: ожидание сигнального состояния объекта 498
14.6.1. Возвращаемое значение 499
14.7. Функция WaitForMultipleObjects: ожидание сигнального состояния объектов 499
14.7.1. Возвращаемое значение 500
14.8. Функция GetOverlappedResult: результат асинхронной операции 501
14.8.1. Возвращаемое значение 502
14.9. Функция DeviceIoControl: прямое управление драйвером 502
14.9.1. Возвращаемое значение 504
14.10. Функция CancelIo: прерывание операции 504
14.10.1. Возвращаемое значение 504
14.11. Функция QueryDosDevice: получение имени устройства по его DOS-имени 505
14.11.1. Возвращаемое значение 505
14.11.2. Пример вызова 506
14.12. Функция DefineDosDevice: операции с DOS-именем устройства 507
14.12.1. Возвращаемое значение 507
14.12.2. Пример вызова 507
Глава 15. Структуры и функции Windows для последовательных портов 509
15.1. Структура настроек порта COMMCONFIG 509
15.2. Структура свойств порта COMMPROP 511
15.3. Структура тайм-аутов COMMTIMEOUTS 518
15.4. Структура статуса порта COMSTAT 520
15.5. Структура DCB 522
15.6. Функция BuildCommDCB: создание структуры DCB из строки 528
15.6.1. Дополнительные сведения 530
15.6.2. Возвращаемое значение 530
15.6.3. Пример вызова 530
15.7. Функция BuildCommDCBAndTimeouts: создание структуры DCB и тайм-аутов из строки 531
15.8. Функции SetCommBreak и ClearCommBreak: управление выводом данных 531
15.8.1. Возвращаемое значение 532
15.9. Функция ClearCommError: получение и сброс ошибок порта 532
15.9.1. Возвращаемое значение 533
15.10. Функция EscapeCommFunction: управление портом 534
15.10.1. Возвращаемое значение 534
15.11. Функции GetCommMask и SetCommMask: маска вызова событий 535
15.11.1. Возвращаемое значение 535
15.12. Функция WaitCommEvent: ожидание события COM-порта 536
15.12.1. Возвращаемое значение 537
15.12.2. Дополнительные сведения 537
15.12.3. Пример вызова 537
15.13. Функции GetCommConfig и SetCommConfig: конфигурирование параметров порта 540
15.13.1. Возвращаемое значение 541
15.13.2. Пример вызова 541
15.14. Функция CommConfigDialog: диалог конфигурирования порта 542
15.14.1. Возвращаемое значение 543
15.14.2. Дополнительные сведения 543
15.14.3. Пример вызова 543
15.15. Функция GetCommProperties: прочитать свойства порта 544
15.15.1. Возвращаемое значение 544
15.15.2. Пример вызова 544
15.16. Функции GetCommState и SetCommState: состояние порта 544
15.16.1. Возвращаемое значение 545
15.16.2. Пример вызова 545
15.17. Функции GetCommTimeouts и SetCommTimeouts: тайм-ауты порта 546
15.17.1. Возвращаемое значение 547
15.17.2. Пример вызова 547
15.18. Функция PurgeComm: сброс буферов порта 547
15.18.1. Возвращаемое значение 548
15.18.2. Пример вызова 548
15.19. Функция SetupComm: конфигурирование размеров буферов 548
15.19.1. Возвращаемое значение 550
15.20. Функции GetDefaultCommConfig и SetDefaultCommConfig: настройки порта по умолчанию 550
15.20.1. Возвращаемое значение 551
15.21. Функция TransmitCommChar: передача специальных символов 551
15.21.1. Возвращаемое значение 551
15.22. Функция GetCommModemStatus: статус модема 552
15.22.1. Возвращаемое значение 552
15.22.2. Пример вызова 553
15.23. Функция EnumPorts: перечисление портов 553
15.23.1. Дополнительные сведения 555
15.23.2. Возвращаемое значение 555
15.23.3. Пример вызова 555
Глава 16. Структуры и функции Windows Setup API 557
16.1. Функция SetupDiGetClassDevs: перечисление устройств 557
16.1.1. Возвращаемое значение 558
16.2. Функция SetupDiDestroyDeviceInfoList: освобождение блока описания устройства 558
16.2.1. Возвращаемое значение 559
16.3. Функция SetupDiEnumDeviceInterfaces: информация об устройстве 559
16.3.1. Возвращаемое значение 560
16.4. Функция SetupDiGetDeviceInterfaceDetail: детальная информация об устройстве 561
16.5. Функция SetupDiEnumDeviceInfo: информация об устройстве 562
16.6. Функция SetupDiGetDeviceRegistryProperty: получение Plug and Play свойств устройства 564
16.7. Функция CM_Get_DevNode_Status: статус устройства 565
16.8. Функция CM_Request_Device_Eject: безопасное извлечение устройства 566
Глава 17. Структуры и функции Windows HID API 568
17.1. Функция HidD_Hello: проверка библиотеки 568
17.2. Функция HidD_GetHidGuid: получение GUID 569
17.3. Функция HidD_GetPreparsedData: создание описателя устройства 570
17.4. Функция HidD_FreePreparsedData: освобождение описателя устройства 571
17.5. Функция HidD_GetFeature: получение Feature-репорта 571
17.6. Функция HidD_SetFeature: передача Feature-репорта 573
17.7. Функция HidD_GetNumInputBuffers: получение числа буферов 573
17.8. Функция HidD_SetNumInputBuffers: установка числа буферов 574
17.9. Функция HidD_GetAttributes: получение атрибутов устройства 575
17.10. Функция HidD_GetManufacturerString: получение строки производителя 576
17.11. Функция HidD_GetProductString: получение строки продукта 578
17.12. Функция HidD_GetSerialNumberString: получение строки серийного номера 578
17.13. Функция HidD_GetIndexedString: получение строки по индексу 579
17.14. Функция HidD_GetInputReport: получение Input-репорта 580
17.15. Функция HidD_SetOutputReport: передача Output-репорта 581
17.16. Функция HidP_GetCaps: получение свойств устройства 581
17.17. Функция HidP_MaxDataListLength: получение размеров репортов 584
17.18. Функция HidD_FlushQueue: сброс буферов 585
17.19. Функция HidP_GetLinkCollectionNodes: дерево коллекций 585
17.20. Функции HidP_GetScaledUsageValue и HidP_SetScaledUsageValue: получение и задание преобразованных значений 586
17.21. Функция HidP_MaxUsageListLength: размер буфера для кодов клавиш 587
17.22. Функция HidP_UsageListDifference: различие между массивами 587
ПРИЛОЖЕНИЯ 589
Приложение 1. Дополнительные функции 591
Приложение 2. Компиляция примеров в других версиях Delphi 592
Приложение 3. Таблица идентификаторов языков (LangID) 593
Приложение 4. Таблица кодов производителей (Vendor ID, Device ID) 596
Приложение 5. Как создать ярлык Device Manager 598
Приложение 6. Часто задаваемые вопросы 599
Приложение 7. Описание компакт-диска 600
Литература 602
Предметный указатель 603
XIV Оглавление XIII Оглавление