Программирование USB*устройств. Программирование USB в Android

Но ведь мало только физически подсоединить устройство к компьютеру, нужно еще и наладить обмен данными между ними. Как же выбрать порт и организовать подключение? Несколько лет назад стандартным решением было использование COM-порта. Кстати, до сих пор различные специалисты доустанавливают на промышленные компьютеры по 8, по 16, а то и по 32 COM-порта (есть целая категория различных PCI-плат расширения последовательных портов, контроллеров и т. д.). Таким образом, если нужно подключить несколько внешних устройств с интерфейсом RS-232, могут потребоваться дорогие адаптеры и экзотические платы расширения, которые по старой традиции неделями плывут в Россию на пароходах. Кстати, название обычного переходника «адаптер DB9m/DB25f» у менеджера компьютерного магазина может вызвать разве что раздражение.

Что такое HID-устройство

Сейчас практически все устройства подключаются к компьютеру через USB-интерфейс. Поэтому во многих новых ПК COM-порт отсутствует вообще.

USB-интерфейс - типовое решение по сопряжению нового внешнего устройства с компьютером, точнее, это HID-интерфейс, базирующийся на протоколе USB 1.1.

Хотя многие и считают, что HID-интерфейс (Human Interface Device) предназначен исключительно для клавиатуры, мыши и джойстика, он годится для множества решений, связанных с сопряжением внешних устройств и компьютера.

Если пользователю необходимо производить низкоскоростной обмен данными (до 64 кбит/c) и при этом желательно сократить время на утомительной разработке собственных драйверов, то ему вполне подойдет HID. На выходе же получится простое и вполне современное решение на базе стандартного программного USB-интерфейса с гарантированной поддержкой на всех распространенных программных платформах.

Свойства HID-устройства

С точки зрения организации программной поддержки HID-устройства, все выглядит достаточно привлекательно: для работы под управлением Windows можно быстро создавать понятный компактный код на базе готовых проверенных алгоритмов. При этом у разработчика останется масса времени на реализацию собственного протокола обмена данными верхнего уровня, поскольку необходимый уровень абстрагирования уже организован за счет HID-протокола (см. таблицу). Кроме того, программисту легко проводить отладку написанного протокола обмена (разумеется, при наличии работающего HID-устройства) - благодаря относительной жесткости самого протокола достаточно просто разработать программу поддержки устройства компьютером. Еще бы! Массу работы уже взял на себя создатель HID-устройства.

Организация обмена данными между HID-устройством и компьютером

Чтобы описать взаимодействие HID-устройства с компьютером, употребим термин «хост». В данном случае под ним понимается управляющее устройство в общей физической архитектуре взаимодействия по USB-протоколу. Так, все порты в компьютере - хосты. К ним можно подключать различные USB-устройства (флэшки, мыши, веб-камеры, фотоаппараты и проч.), которые хоста не имеют. Хост обеспечивает обнаружение, подключение, отключение, конфигурирование устройств, а также сбор статистики и управление энергопотреблением.

HID-устройство может само установить частоту опроса, во время которого выясняется наличие в нем каких-либо новых данных. Значит, даже на таком низком уровне программист может довериться системе, поскольку частота опроса и другие параметры обмена данными должны быть заранее заданы в программе контроллера HID-устройства. Этим протокол HID отличается от общего описания USB 1.1 или USB 2.0, в котором нет жестких требований к организации протокола. Однако при специфических задачах, требующих повышенного уровня безопасности, может оказаться довольно сложно избавиться от циклических опросов, когда постоянно передаются почти одни и те же блоки данных.

Особенности программирования HID-устройств

HID-устройства имеют специальные дескрипторы. Когда хост определит, что устройство принадлежит к классу HID, он передает управление им соответствующему драйверу. Предполагается, что дальнейший обмен данными ведется под его руководством.

В Windows за доступ к HID-устройствам отвечает системная служба HidServ. Подробнее о функциях запросов к HID-устройствам и других особенностях работы с HID-драйвером рассказывается в работе П. В. Агурова «Интерфейс USB. Практика использования и программирования» (СПб.: БХВ-Петербург, 2005).

Программирование HID-устройств на «верхнем уровне»

Нелегкую жизнь «прикладных» программистов, работающих на Паскале, облегчает проверенный модуль HID. PAS, программная оболочка для hid. dll (Hid User Library - как указано в свойствах файла). В комментариях к файлу сообщается, что в основе его лежат модули hidsdi.h и hidpi.h корпорации Microsoft. А сам файл HID. PAS - часть пакета JEDI ().

Для работы с HID-устройством в среде Delphi for win32 применяется компонент TJvHidDeviceController, представляющий собой удобный глобальный менеджер для доступа к HID-устройствам. А уже на его базе можно получить объектный экземпляр для работы с конкретным устройством.

Основные свойства и события компонента TJvHidDeviceController

Рассмотрим компонент TJvHidDeviceController более подробно. Событие OnArrival срабатывает на поступление (подключение) в систему HID-устройства, доступ к устройству предоставляется в обработчике этого события через экземпляр класса TJvHidDevice. Простое событие OnDeviceChange реагирует на изменение состояния устройства, оно только сигнализирует об изменениях в системе. Событие OnDeviceData срабатывает при поступлении данных от одного из HID-устройств и передает обработчику следующее: HidDev: TJvHidDevice; - устрой-ство, от которого были получены данные;

Событие OnDeviceDataError уведомляет об ошибке передачи данных, передавая в процедуру обработки параметры HidDev: TJvHidDevice; - HID-устройство и Error: DWORD; - код ошибки. Событие OnDeviceUnplug уведомляет об извлечении устройства из списка установленных в системе. Типы обработчиков событий на Plug и Unplug одинаковы (в исходном тексте: TJvHidUnplugEvent = TJvHidPlugEvent). В обработчик передается объект класса TJvHidDevice, соответствующий HID-устройству.

Для последовательного перечисления имеющихся в системе HID-устройств по вызову метода Enumerate предназначено событие OnEnumerate, т. е. в обработчике события найденные устройства последовательно передаются в виде объектов. Это событие принудительно инициируется методом Enumerate, использующимся для «проведения» имеющихся HID-устройств через обработчик, например при ревизии состояния HID-устройств по инициативе хоста (компьютера).

Событие OnRemoval срабатывает на физическое извлечение устройства из системы и имеет тот же тип обработчика TJvHidUnplugEvent, что и для OnDeviceUnplug. Функция CountByProductName выдает количество устройств, удовлетворяющих указанному в аргументе имени продукта, а CountByVendorName - указанному в аргументе имени производителя.

Основные свойства и события класса TJvHidDevice

Класс TJvHidDevice - виртуальное представление отдельно взятого HID-устройства. Новый объект этого класса можно получить, как было уже сказано, из события OnArrival или OnEnumerate. Функционал классов TJvHidDeviceController и TJvHidDevice частично дублируется, поскольку в первом из них интегрированы общий инструментарий для работы с набором имеющихся в системе HID-устройств и механизм доступа к одному из них. Устройство можно однозначно идентифицировать по свойствам SerialNumber, ProductName и VendorName. Чтобы получить сведения о поступлении данных с применением такого объекта, можно воспользоваться событием OnData. Отсылка данных ведется через метод WriteFile (в строгом смысле - через функцию). WriteFile - это оболочка системной функции WriteFile (kernel32).

Чтобы проконтролировать факт извлечения устройства, следует присвоить свой обработчик событию OnUnplug. Перед началом обмена данными с HID-устройством нужно удостовериться в самой возможности такого обмена с помощью HasReadWriteAccess. В этом классе на возникновение ошибки обмена данными даже есть отдельное событие OnDataError.

А теперь рассмотрим фрагменты кода из «живого» проекта, реализующего тестовое клиентское приложение для организации обмена данными с нестандартным устройством - пластиковыми чип-картами на базе HID. В борьбе за реализм автор взял на себя смелость не выкидывать из листингов «лишние» технологические обвязки кода.

Метод ScanDevices (листинг 1) предназначен для инициирования процесса поиска в системе необходимого HID-устройства. Большая часть кода, за исключением вызова метода Enumerate, необязательна и обеспечивает гибкость приложения, например, для того, чтобы в эту же тестовую программу можно было добавить возможность работы по интерфейсу, отличному от HID. Метод AddError выводит в окно отладочную информацию в процессе работы программы.

В листинге 2 приведен обработчик события OnEnumerate для поиска необходимого внешнего устройства. Для простоты будем считать, что программа может работать только с одним устройством нужного ей типа.

Прежде чем рассматривать дальнейшую реализацию проекта, следует немного рассказать о принятом формате обмена данными верхнего уровня, т. е. о структуре, призванной быть посредником между методами приема-передачи данных и конкретной решаемой прикладной задачей. Дело в том, что здесь разработчику предоставляется возможность реализовать свои творческие способности. Вернее, разработчикам, потому что процесс создания нового протокола очень часто бывает двусторонним, и при этом первую скрипку играет тот, кому труднее реализовывать алгоритм обмена. В общем, каким бы ни был протокол обмена, всегда приятно делать каждую программную сущность максимально наглядной и самодостаточной, пусть даже в ущерб некоторым общепринятым традициям. Ибо лучшее решение - то, которое будет реализовано в сжатые сроки с минимальной привязкой к программной среде и с большими возможностями дальнейшего развития. На основе этих принципов был создан протокол обмена верхнего уровня, где главное понятие - «команда». Из листинга 3 видно, насколько автор любит строковые данные, не раз спасавшие его при отладке программных модулей. Как же замечательно, что у нас вообще есть тип String! Все команды протокола делятся на категории (классы), внутри которых существует код команды, однозначно характеризующий ее назначение. Параметр edParam служит для отсылки данных в устройство, а параметр edAnswerData содержит в себе полученные от устройства данные. Строковый тип описанных членов записи позволяет свободно и наглядно манипулировать данными в формате HEX-строки. И что самое приятное, формат описанной записи идеологически стоит где-то посередине между ее непосредственным назначением и различными формами ее представления (INI, HEX, XML и т. д.)

Выполнение команды, т. е. отсылка данных в устройство, реализовано с применением отсылки пакетов данных длиной 8 байт (листинг 4). Эта длина - не единственное решение, такой выбор продиктован требованиями протокола верхнего уровня и в каждом конкретном случае может быть другим. Это, что называется, дело вкуса. Странный флаг IsUSBMode в методе ExecuteCommand (листинг 5 на «Мир ПК-диске») оставлен как напоминание о том, что вместо работы с USB нам может потребоваться использовать COM-порт или какой-то другой интерфейс. В начале отсылаемой группы данных в устройство передается синхросерия произвольно выбранного формата (например, 3E3E3E2B), сообщающая устройству, что у него на входе вполне легальные данные. Напомню, что в данном случае речь идет не столько о HID, сколько о специфическом протоколе верхнего уровня, идеологически оторванном от «железа» и предназначенном для решения особых прикладных задач.

В обработчике GetDataExecutor полученных от устройства данных (пакет по 8 байт) использовано специально созданное событие OnNewInputData для передачи первично обработанных данных на дальнейшую обработку, причем с указанием их старого и нового значений (листинг 6 на «Мир ПК-диске»). Таким образом, события поступления необработанных данных и указание на дальнейшую обработку развязываются, позволяя добавлять какой-то специфический алгоритм предупреждения на раннем этапе ошибочной, повторной или ненужной входной информации.

Представленные здесь примеры работы с HID-устройством иллюстрируют общую идею статьи - относительную простоту программирования нестандартных HID-устройств средствами Delphi.

Хорошая книга, многое объясняет. Пригодится тем, кто хочет понять как происходит передача данных по шине USB.

Введение 1
Для кого эта книга: 2
Что вы найдете в книге 2
Программные требования 3
Аппаратные требования 4
О программном коде 4
Краткое описание глав 4
Обозначения 6
Благодарности 7
ЧАСТЬ I. ВВЕДЕНИЕ В USB 9
Глава 1. Что такое USB 11
1.1. История USB 11
1.2. Сравнение USB с другими интерфейсами 14
1.3. Основные понятия USB 16
1.3.1. Общая архитектура шины 16
1.3.2. Физическая и логическая архитектура шины 16
1.3.3. Составляющие USB 18
1.3.4. Свойства USB-устройств 18
1.3.5. Свойства хабов 19
1.3.6. Свойства хоста 20
1.4. Примеры USB-устройств 20
1.4.1. Мышь и клавиатура., 21
1.4.2. Мониторы 21
1.4.3. Переходники USB-to-COM и USB-to-LPT 22
1.4.4. Сканеры 23
1.4.5. Модемы 23
1.4.6. Звуковые колонки 24
1.4.7. Флеш-диски 25
1.4.8. Хабы 28
1.4.9. Измерительная техника 28
1.4.10. Экзотические устройства 29
1.5. Сетевое соединение через USB 30
1.5.1. Конвертер USB-Ethernet 31
1.5.2. Прямое соединение через USB-порт 31
1.6. Передача данных 31
1.6.1. Принципы передачи данных 32
1.6.2. Механизм прерываний 32
1.6.3. Интерфейсы хост-адаптера 32
1.6.4. Возможность прямого доступа к памяти 34
1.6.5. Режимы передачи данных 34
1.7. Установка и конфигурирование USB-устройств 35
1.7.1. Настройки BIOS для USB 38
1.7.2. Устранение проблем 41
1.8. Ограничения USB 45
1.9. Если вы покупаете компьютер 46
1.9.1. HS и USB 2.0 - не одно и то же! 46
1.9.2. Системная плата 47
1.9.3. Корпус 48
1.9.4. USB для “старых” моделей компьютеров 48
1.10. Интернет-ресурсы к этой главе 49
Глава 2. Аппаратное обеспечение USB 51
2.1. Кабели и разъемы 51
2.1.1. Типы кабелей 52
2.1.2. Длина кабеля 53
2.1.3. Разъемы 53
2.2. Физический интерфейс 55
2.2.1. Кодирование данных 57
2.2.2. Идентификация устройств 58
2.3. Питание 59
2.3.1. Типы питания USB-устройств 59
2.3.2. Управление энергопотреблением 60
2.3.3. Вход в режим низкого энергопотребления 61
2.4. Интернет-ресурсы к этой главе 61
ЧАСТЬ II. ВНУТРЕННЯЯ ОРГАНИЗАЦИЯ USB 63
Глава 3. Внутренняя организация шины 65
3.1. Логические уровни обмена данными 65
3.1.1. Уровень клиентского ПО 66
3.1.2. Уровень системного драйвера USB 67
3.1.3. Уровень хост-контроллера интерфейса 68
3.1.4. Уровень шины периферийного устройства 68
3.1.5. Уровень логического USB-устройства 69
3.1.6. Функциональный уровень USB-устройства 69
3.2. Передача данных по уровням 69
3.3. Типы передач данных 71
3.4. Синхронизация при изохронной передаче 73
3.5. Кадры 77
3.6. Конечные точки 78
3.7. Каналы 79
3.8. Пакеты 81
3.8.1. Формат пакетов-маркеров IN, OUT, SETUP и PING 83
3.8.2. Формат пакета SOF 83
3.8.3. Формат пакета данных 84
3.8.4. Формат пакета подтверждения < 84
3.8.5. Формат пакета SPLIT * 84
3.9. Контрольная сумма 85
3.9.1. Алгоритм вычисления CRC 86
3.9.2. Программное вычисление CRC 87
3.10. Транзакции 90
3.10.1. Типы транзакций 91
3.10.2. Подтверждение транзакций и управление потоком 92
3.10.3. Протоколы транзакций 93
Глава 4. Внутренняя организация устройства 96
4.1. Запросы к USB-устройствам 96
4.1.1. Конфигурационный пакет 96
4.1.2. Стандартные запросы к устройствам 99
4.1.3. Дескрипторы устройства 105
Глава 5. Внутренняя организация хоста и хабов 123
5.1. Хабы 123
5.1.1. Взаимодействие хост-контроллера с хабом 126
5.1.2. Дескриптор хаба 127
5.1.3. Запросы хабов 129
5.1.4. Запрос CLEAR_HUB_FEATURE 130
5.1.5. Запрос CLEAR PORT_FEATURE 130
5.1.6. Запрос GET_BUS_STA ТЕ 131
5.1.7. Запрос GET_HUB_DESCRfPTOR 131
5.1.8. Запрос GET_HUB_STATUS 131
5.1.9. Запрос GET_PORT_STA TUS 132
5.1.10. Запрос SET_HUB_DESCRIPTOR 134
5.1.11. Запрос SET_HUB_FEATURE 134
5.1.12. Запрос SET PORT FEATURE. 134
5.2. Совместная работа устройств с разными скоростями 135
Глава 6. USB без ПК 137
6.1. Разъемы OTG 138
6.2. Типы OTG-устройств 138
6.3. Дескриптор OTG-устройства 139
6.4. Интернет-ресурсы к этой главе 140
ЧАСТЬ III. ПРАКТИКА ПРОГРАММИРОВАНИЯ 141
Глава 7. Поддержка USB в Windows 143
7.1. Модель WDM 144
7.2. Взаимодействие с USB-драйвером 146
Глава 8. HID-устройства * 149
8.1. Свойства HID-устройства 149
8.2. Порядок обмена данными с HID-устройством 151
8.3. Установка HID-устройства 152
8.4. Идентификация HID-устройства 152
8.4.1. Идентификация загрузочных устройств 153
8.4.2. Дескриптор конфигурации HID-устройства 153
8.4.3. HID-дескриптор 154
8.4.4. Дескриптор репорта 156
8.5. Структура дескриптора репорта 156
8.5.1. Структура элементов репорта 156
8.5.2. Типы элементов репорта 157
8.5.3. Примеры дескрипторов 165
8.6. Запросы к HID-устройству 168
8.6.1. Запрос GET_REPORT. 169
8.6.2. Запрос SET_REPORT 169
8.6.3. Запрос GETJDLE. 170
8.6.4. Запрос SETJDLE 170
8.6.5. Запрос GET_PROTOCOL 171
8.6.6. Запрос SET_PROTOCOL 171
8.7. Инструментальные средства 171
8.8. Взаимодействие с HID-драйвером 172
Глава 9. Введение в WDM 181
9.1. Драйверные слои 183
9.2. Символьные имена устройств 184
9.3. Основные процедуры драйвера WDM 189
9.3.1. Процедура DriverEntry 190
9.3.2. Процедура AddDevice 192
9.3.3. Процедура Unload 194
9.3.4. Рабочие процедуры драйвера 196
9.3.5. Обслуживание запросов IOCTL 203
9.4. Загрузка драйвера и обращение к процедурам драйвера 209
9.4.1. Процедура работы с драйвером 209
9.4.2. Регистрация драйвера 210
9.4.3. Обращение к рабочим процедурам 217
9.4.4. Хранение драйвера внутри исполняемого файла 218
9.5. Инструменты создания драйверов 220
9.5.1. NuMega Driver Studio 220
9.5.2. Jungo WinDriver 220
9.5.3. Jungo KernelDriver 220
Глава 10. Спецификация PnP для USB 221
10.1. Общие сведения о системе Plug and Play 221
10.1.1. Задачи и функции Plug and Play 221
10.1.2. Запуск процедуры PnP 222
10.1.3. Программные компоненты PnP 224
10.2. Plug and Play для USB 225
10.2.1. Конфигурирование устройств USB 226
10.2.2. Нумерация устройств USB 226
10.2.3. PnP-идентификаторы устройств USB 228
10.3. Получение списка USB-устройств 229
10.4. INF-файл 234
10.4.1. Структура INF-файла 234
10.4.2. Секция Version 235
10.4.3. Секция Manufacturer 237
10.4.4. Секция DestinationDirs 239
10.4.5. Секция описания модели 241
10.4.6. Секция xxx.AddReg и xxx.DelReg. 242
10.4.7. Секция ххх.LogConfig 244
10.4.8. Секция xxx.CopyFiles 244
10.4.9. Секция Strings 245
10.4.10. Связи секций 246
10.4.11. Создание и тестирование INF-файлов 247
10.4.12. Установка устройств с помощью INF-файла 248
10.5. Ветки реестра для USB 249
Глава 11. Функции BIOS 251
11.1. Сервис BIOS 1АН 251
11.1.1. Функция В101Н - определение наличия PCI BIOS 252
11.1.2. Функция В102Н - поиск PCI-устройства по идентификаторам
устройства и производителя 253
11.1.3. Функция В103Н - поиск PCI-устройства по коду класса 254
11.1.4. Функция В108Н - чтение регистра конфигурации (Byte) 255
11.1.5. Функция ВЮ9Н - чтение регистра конфигурации (Word) 256
11.1.6. Функция В10АН - чтение регистра конфигурации (DWord) 256
11.1.7. Функция В10ВН - запись регистра конфигурации (Byte) 257
11.1.8. Функция В10СН - запись регистра конфигурации (Word) 257
11.1.9. Функция B10DH - запись регистра конфигурации (DWord) 258
11.2. Пример использования 259
ЧАСТЬ IV. СОЗДАНИЕ USB-УСТРОЙСТВ 283
Глава 12. USB-периферия 285
12.1. Микросхемы Atmel 286
12.1.1. Микроконтроллеры с архитектурой MSC-51 286
12.1.2. Контроллеры хабов 289
12.1.3. Микропроцессоры-хабы с ядром AVR 289
12.1.4. Другие микросхемы Atmel 290
12.2. Микросхемы Cygnal 291
12.2.1. Микропроцессоры C8051F320 и C8051F321 291
12.2.2. Другие микросхемы Cygnal 293
12.3. Микросхемы FTDI 296
12.3.1. Микросхемы FT232AM и FT232BM 297
12.3.2. Микросхемы FT245AM и FT245BM 298
12.3.3. Микросхема FT2232BM 299
12.3.4. Микросхема FT8U100AX 300
12.3.5. Отладочные комплекты и модули 301
12.3.6. Драйверы 302
12.3.7. Дополнительные утилиты 303
12.3.8. Другие модули 304
12.4. Микросхемы Intel 304
12.5. Микросхемы Microchip 308
12.6. Микросхемы Motorola 308
12.7. Микросхемы Philips 309
12.7.1. Микросхемы USB 310
12.7.2. Хабы 311
12.7.3. Другие микросхемы Philips 313
12.8. Микросхемы Texas Instruments 314
12.9. Микросхемы Trans Dimension 317
12.10. Микросхемы защиты питания 318
12.11. Интернет-ресурсы к этой главе 319
Глава 13. HID-устройство на основе Atmel АТ89С5131 322
13.1. Структурная схема АТ89С5131 322
13.2. USB-регистры АТ89С5131 324
13.2.1. Регистр USBCON 324
13.2.2. Регистр USBADDR 326
13.2.3. Регистр USBINT 327
13.2.4. Регистр USBIEN 328
13.2.5. Регистр UEPNUM. 329
13.2.6. Регистр UEPCONX 330
13.2.7. Регистр UEPSTAX. 331
13.2.8. Регистр UEPRST. 334
13.2.9. Регистр UEPINT. 335
13.2.10. Регистр UEPIEN 336
13.2.11. Регистр UEPDATX 337
13.2.12. Регистр UBYCTLX 337
13.2.13. Регистр UFNUML 338
13.2.14. Регистр UFNUMH. 338
13.3. Схемотехника АТ89С5131 338
13.4. Инструменты программирования 339
13.4.1. Компилятор 341
13.4.2. Программатор 342
13.5. Программа для микропроцессора 349
13.5.1. Первая версия программы для АТ89С5131 349
13.5.2. Добавляем строковые дескрипторы 369
13.5.3. Добавление конечных точек 374
13.5.4. Создание HID-устройства 377
13.5.5. Обмен данными с HID-устройством 381
13.6. Чтение репортов в Windows 388
13.7. Дополнительные функции Windows ХР 396
13.8. Устройство с несколькими репортами 397
Глава 14. Создание USB-устройства на основе ATMEL АТ89С5131 402
14.1. He-HID-устройство 402
14.2. Создание драйвера с помощью Driver Studio 405
14.2.1. Несколько слов о библиотеке Driver Studio 407
14.2.2. Другие классы Driver Studio 411
14.2.3. Создание шаблона драйвера с помощью Driver Studio 412
14.2.4. Доработка шаблона драйвера 422
14.2.5. Базовые методы класса устройства 423
14.2.6. Реализация чтения данных 426
14.2.7. Установка драйвера 428
14.2.8. Программа чтения данных 429
14.2.9. Чтение данных с конечных точек других типов 438
14.2.10. “Чистый” USB-драйвер 439
Глава 15. Использование микросхем FTDI 457
15.1. Функциональная схема FT232BM 457
15.2. Схемотехника FT232BM 460
15.3. Функции D2XX 460
15.4. Переход от СОМ к USB 465
15.4.1. Описание схемы преобразователя 465
15.4.2. Установка скорости обмена 467
ЧАСТЬ V. СПРАВОЧНИК 469
Глава 16. Базовые функции Windows 471
16.1. Функции CreateFile и CloseHandle: открытие и закрытие объекта.471
16.1.1. Дополнительные сведения 472
16.1.2. Возвращаемое значение 472
16.1.3. Пример вызова 472
16.2. Функция Read File: чтение данных 473
16.2.1. Дополнительные сведения 474
16.2.2. Возвращаемое значение 474
16.2.3. Пример вызова 474
16.3. Функция WriteFile: передача данных 475
16.3.1. Дополнительные сведения 476
16.3.2. Возвращаемое значение 476
16.3.3. Пример вызова 476
16.4. Функция ReadFileEx. АРС-чтение данных 477
16.4.1. Возвращаемое значение 479
16.4.2. Дополнительные сведения 479
16.4.3. Пример вызова 479
16.5. Функция WriteFileEx: АРС-передача данных 480
16.5.1. Возвращаемое значение 481
16.5.2. Пример вызова 481
16.6. Функция WaitForSingleObject ожидание сигнального
состояния объекта 482
16.6.1. Возвращаемое значение 482
16.7. Функция WaitForMultipleObjects: ожидание сигнального
состояния объектов 483
16.7.1. Возвращаемое значение 484
16.8. Функция GetOverlappedResult результат асинхронной операции 484
16.8.1. Возвращаемое значение 485
16.9. Функция DeviceIoControl: прямое управление драйвером 485
16.9.1. Возвращаемое значение 487
16.10. Функция QueryDosDevice: получение имени устройства
по его DOS-имени 487
16.10.1. Возвращаемое значение 488
16.10.2. Пример вызова 488
16.11: Функция Define Dos Device: операции с DOS-именем устройства 489
16.11.1. Возвращаемое значение 490
16.11.2. Пример вызова 490
Глава 17. Функции HID API. 492
17.1. Функция HidD_Hello: проверка библиотеки 492
17.2. Функция HidD_GetHidGuid: получение GUID 492
17.3. Функция HidD_GetPreparsedData: создание описателя устройства 493
17.4. Функция HidD_FreePreparsedData: освобождение описателя устройства 493
17.5. Функция HidD_GetFeature: получение FEATURE-репорта 494
17.6. Функция HidD_SetFeature: передача FEATURE-репорта 494
17.7. Функция HidD_GetNumInputBuffers: получение числа буферов 495
17.8. Функция HidD_SetNumInputBuffers: установка числа буферов 495
17.9. Функция HidD_GetAttribntes: получение атрибутов устройства 495
17.10. Функция HidD_GetMamifactnrerStnng. получение строки производителя 496
17.11. Функция HidD_GetProductString. получение строки продукта 497
17.12. Функция HidD_ Get Serial MumberString. получение строки
серийного номера 497
17.13. Функция HidD_GetIndexedString. получение строки по индексу 498
17.14. Функция HidDjGetlnputReporr. получение INPUT-репорта 498
17.15. Функция HidD_SetOutputReport. передача OUTPUT-репорта 499
17.16. Функция HidP_GetCaps: получение свойств устройства 499
17.17. Функция HidP_MaxDataListLength: получение размеров репортов 500
Глава 18. Хост-контроллер UCH 502
18.1. Регистры управления хост-контроллером 502
18.1.1. Регистр команды USB (USBCMD) ..504
18.1.2. Регистр состояния USB (USBSTS) 506
18.1.3. Регистр управления прерываниями (USBINTR) 506
18.1.4. Регистр номера кадра (FRNUM) 507
18.1.5. Регистр базового адреса кадра (FLBASEADD) 508
18.1.6. Регистр модификатора начала кадра (SOFMOD) 508
18.1.7. Регистр состояния и управления порта (PORTSC) 509
18.2. Структуры данных хост-контроллера UCH 510
18.2.1. Список кадров 510
18.2.2. Дескриптор передачи i 511
18.2.3. Заголовок очереди 514
18.3. Обработка списка дескрипторов UCH 516
Глава 19. Инструменты 518
19.1. Средства Microsoft Visual Studio 518
19.1.1. Depends 518
19.1.2. Error Lookup 518
19.1.3. GuidGen 518
19.2. Средства Microsoft DDK 520
19.2.1. DeviceTree 520
19.2.2. DevCon .- 521
19.2.3. Chklnf и Genlnf. 526
19.3. Средства CompuWare Corporation 527
19.3.1. Monitor 527
19.3.2. SymLink 527
19.3.3. EzDriverlnstaller 527
19.3.4. WdmSniff 527
19.4. Средства Syslntemals 528
19.4.1. WinObj 528
19.5. Средства USB Forum 531
19.5.1. HID Descriptor Tool 531
19.6. Средства HDD Software 533
19.7. Средства Sourceforge 533
ПРИЛОЖЕНИЯ 535
Приложение 1. Дополнительные функции 537
Приложение 2. Таблица идентификаторов языков (LangID) 539
Приложение 3. Таблица кодов производителей (Vendor ID, Device ID) 543
Приложение 4. Описание компакт-диска 546
Литература 548
Предметный указатель 549

Но ведь мало только физически подсоединить устройство к компьютеру, нужно еще и наладить обмен данными между ними. Как же выбрать порт и организовать подключение? Несколько лет назад стандартным решением было использование COM-порта. Кстати, до сих пор различные специалисты доустанавливают на промышленные компьютеры по 8, по 16, а то и по 32 COM-порта (есть целая категория различных PCI-плат расширения последовательных портов, контроллеров и т. д.). Таким образом, если нужно подключить несколько внешних устройств с интерфейсом RS-232, могут потребоваться дорогие адаптеры и экзотические платы расширения, которые по старой традиции неделями плывут в Россию на пароходах. Кстати, название обычного переходника «адаптер DB9m/DB25f» у менеджера компьютерного магазина может вызвать разве что раздражение.

Что такое HID-устройство

Сейчас практически все устройства подключаются к компьютеру через USB-интерфейс. Поэтому во многих новых ПК COM-порт отсутствует вообще.

USB-интерфейс - типовое решение по сопряжению нового внешнего устройства с компьютером, точнее, это HID-интерфейс, базирующийся на протоколе USB 1.1.

Хотя многие и считают, что HID-интерфейс (Human Interface Device) предназначен исключительно для клавиатуры, мыши и джойстика, он годится для множества решений, связанных с сопряжением внешних устройств и компьютера.

Если пользователю необходимо производить низкоскоростной обмен данными (до 64 кбит/c) и при этом желательно сократить время на утомительной разработке собственных драйверов, то ему вполне подойдет HID. На выходе же получится простое и вполне современное решение на базе стандартного программного USB-интерфейса с гарантированной поддержкой на всех распространенных программных платформах.

Свойства HID-устройства

С точки зрения организации программной поддержки HID-устройства, все выглядит достаточно привлекательно: для работы под управлением Windows можно быстро создавать понятный компактный код на базе готовых проверенных алгоритмов. При этом у разработчика останется масса времени на реализацию собственного протокола обмена данными верхнего уровня, поскольку необходимый уровень абстрагирования уже организован за счет HID-протокола (см. таблицу). Кроме того, программисту легко проводить отладку написанного протокола обмена (разумеется, при наличии работающего HID-устройства) - благодаря относительной жесткости самого протокола достаточно просто разработать программу поддержки устройства компьютером. Еще бы! Массу работы уже взял на себя создатель HID-устройства.

Организация обмена данными между HID-устройством и компьютером

Чтобы описать взаимодействие HID-устройства с компьютером, употребим термин «хост». В данном случае под ним понимается управляющее устройство в общей физической архитектуре взаимодействия по USB-протоколу. Так, все порты в компьютере - хосты. К ним можно подключать различные USB-устройства (флэшки, мыши, веб-камеры, фотоаппараты и проч.), которые хоста не имеют. Хост обеспечивает обнаружение, подключение, отключение, конфигурирование устройств, а также сбор статистики и управление энергопотреблением.

HID-устройство может само установить частоту опроса, во время которого выясняется наличие в нем каких-либо новых данных. Значит, даже на таком низком уровне программист может довериться системе, поскольку частота опроса и другие параметры обмена данными должны быть заранее заданы в программе контроллера HID-устройства. Этим протокол HID отличается от общего описания USB 1.1 или USB 2.0, в котором нет жестких требований к организации протокола. Однако при специфических задачах, требующих повышенного уровня безопасности, может оказаться довольно сложно избавиться от циклических опросов, когда постоянно передаются почти одни и те же блоки данных.

Особенности программирования HID-устройств

HID-устройства имеют специальные дескрипторы. Когда хост определит, что устройство принадлежит к классу HID, он передает управление им соответствующему драйверу. Предполагается, что дальнейший обмен данными ведется под его руководством.

В Windows за доступ к HID-устройствам отвечает системная служба HidServ. Подробнее о функциях запросов к HID-устройствам и других особенностях работы с HID-драйвером рассказывается в работе П. В. Агурова «Интерфейс USB. Практика использования и программирования» (СПб.: БХВ-Петербург, 2005).

Программирование HID-устройств на «верхнем уровне»

Нелегкую жизнь «прикладных» программистов, работающих на Паскале, облегчает проверенный модуль HID. PAS, программная оболочка для hid. dll (Hid User Library - как указано в свойствах файла). В комментариях к файлу сообщается, что в основе его лежат модули hidsdi.h и hidpi.h корпорации Microsoft. А сам файл HID. PAS - часть пакета JEDI ().

Для работы с HID-устройством в среде Delphi for win32 применяется компонент TJvHidDeviceController, представляющий собой удобный глобальный менеджер для доступа к HID-устройствам. А уже на его базе можно получить объектный экземпляр для работы с конкретным устройством.

Основные свойства и события компонента TJvHidDeviceController

Рассмотрим компонент TJvHidDeviceController более подробно. Событие OnArrival срабатывает на поступление (подключение) в систему HID-устройства, доступ к устройству предоставляется в обработчике этого события через экземпляр класса TJvHidDevice. Простое событие OnDeviceChange реагирует на изменение состояния устройства, оно только сигнализирует об изменениях в системе. Событие OnDeviceData срабатывает при поступлении данных от одного из HID-устройств и передает обработчику следующее: HidDev: TJvHidDevice; - устрой-ство, от которого были получены данные;

Событие OnDeviceDataError уведомляет об ошибке передачи данных, передавая в процедуру обработки параметры HidDev: TJvHidDevice; - HID-устройство и Error: DWORD; - код ошибки. Событие OnDeviceUnplug уведомляет об извлечении устройства из списка установленных в системе. Типы обработчиков событий на Plug и Unplug одинаковы (в исходном тексте: TJvHidUnplugEvent = TJvHidPlugEvent). В обработчик передается объект класса TJvHidDevice, соответствующий HID-устройству.

Для последовательного перечисления имеющихся в системе HID-устройств по вызову метода Enumerate предназначено событие OnEnumerate, т. е. в обработчике события найденные устройства последовательно передаются в виде объектов. Это событие принудительно инициируется методом Enumerate, использующимся для «проведения» имеющихся HID-устройств через обработчик, например при ревизии состояния HID-устройств по инициативе хоста (компьютера).

Событие OnRemoval срабатывает на физическое извлечение устройства из системы и имеет тот же тип обработчика TJvHidUnplugEvent, что и для OnDeviceUnplug. Функция CountByProductName выдает количество устройств, удовлетворяющих указанному в аргументе имени продукта, а CountByVendorName - указанному в аргументе имени производителя.

Основные свойства и события класса TJvHidDevice

Класс TJvHidDevice - виртуальное представление отдельно взятого HID-устройства. Новый объект этого класса можно получить, как было уже сказано, из события OnArrival или OnEnumerate. Функционал классов TJvHidDeviceController и TJvHidDevice частично дублируется, поскольку в первом из них интегрированы общий инструментарий для работы с набором имеющихся в системе HID-устройств и механизм доступа к одному из них. Устройство можно однозначно идентифицировать по свойствам SerialNumber, ProductName и VendorName. Чтобы получить сведения о поступлении данных с применением такого объекта, можно воспользоваться событием OnData. Отсылка данных ведется через метод WriteFile (в строгом смысле - через функцию). WriteFile - это оболочка системной функции WriteFile (kernel32).

Чтобы проконтролировать факт извлечения устройства, следует присвоить свой обработчик событию OnUnplug. Перед началом обмена данными с HID-устройством нужно удостовериться в самой возможности такого обмена с помощью HasReadWriteAccess. В этом классе на возникновение ошибки обмена данными даже есть отдельное событие OnDataError.

А теперь рассмотрим фрагменты кода из «живого» проекта, реализующего тестовое клиентское приложение для организации обмена данными с нестандартным устройством - пластиковыми чип-картами на базе HID. В борьбе за реализм автор взял на себя смелость не выкидывать из листингов «лишние» технологические обвязки кода.

Метод ScanDevices (листинг 1) предназначен для инициирования процесса поиска в системе необходимого HID-устройства. Большая часть кода, за исключением вызова метода Enumerate, необязательна и обеспечивает гибкость приложения, например, для того, чтобы в эту же тестовую программу можно было добавить возможность работы по интерфейсу, отличному от HID. Метод AddError выводит в окно отладочную информацию в процессе работы программы.

В листинге 2 приведен обработчик события OnEnumerate для поиска необходимого внешнего устройства. Для простоты будем считать, что программа может работать только с одним устройством нужного ей типа.

Прежде чем рассматривать дальнейшую реализацию проекта, следует немного рассказать о принятом формате обмена данными верхнего уровня, т. е. о структуре, призванной быть посредником между методами приема-передачи данных и конкретной решаемой прикладной задачей. Дело в том, что здесь разработчику предоставляется возможность реализовать свои творческие способности. Вернее, разработчикам, потому что процесс создания нового протокола очень часто бывает двусторонним, и при этом первую скрипку играет тот, кому труднее реализовывать алгоритм обмена. В общем, каким бы ни был протокол обмена, всегда приятно делать каждую программную сущность максимально наглядной и самодостаточной, пусть даже в ущерб некоторым общепринятым традициям. Ибо лучшее решение - то, которое будет реализовано в сжатые сроки с минимальной привязкой к программной среде и с большими возможностями дальнейшего развития. На основе этих принципов был создан протокол обмена верхнего уровня, где главное понятие - «команда». Из листинга 3 видно, насколько автор любит строковые данные, не раз спасавшие его при отладке программных модулей. Как же замечательно, что у нас вообще есть тип String! Все команды протокола делятся на категории (классы), внутри которых существует код команды, однозначно характеризующий ее назначение. Параметр edParam служит для отсылки данных в устройство, а параметр edAnswerData содержит в себе полученные от устройства данные. Строковый тип описанных членов записи позволяет свободно и наглядно манипулировать данными в формате HEX-строки. И что самое приятное, формат описанной записи идеологически стоит где-то посередине между ее непосредственным назначением и различными формами ее представления (INI, HEX, XML и т. д.)

Выполнение команды, т. е. отсылка данных в устройство, реализовано с применением отсылки пакетов данных длиной 8 байт (листинг 4). Эта длина - не единственное решение, такой выбор продиктован требованиями протокола верхнего уровня и в каждом конкретном случае может быть другим. Это, что называется, дело вкуса. Странный флаг IsUSBMode в методе ExecuteCommand (листинг 5 на «Мир ПК-диске») оставлен как напоминание о том, что вместо работы с USB нам может потребоваться использовать COM-порт или какой-то другой интерфейс. В начале отсылаемой группы данных в устройство передается синхросерия произвольно выбранного формата (например, 3E3E3E2B), сообщающая устройству, что у него на входе вполне легальные данные. Напомню, что в данном случае речь идет не столько о HID, сколько о специфическом протоколе верхнего уровня, идеологически оторванном от «железа» и предназначенном для решения особых прикладных задач.

В обработчике GetDataExecutor полученных от устройства данных (пакет по 8 байт) использовано специально созданное событие OnNewInputData для передачи первично обработанных данных на дальнейшую обработку, причем с указанием их старого и нового значений (листинг 6 на «Мир ПК-диске»). Таким образом, события поступления необработанных данных и указание на дальнейшую обработку развязываются, позволяя добавлять какой-то специфический алгоритм предупреждения на раннем этапе ошибочной, повторной или ненужной входной информации.

Представленные здесь примеры работы с HID-устройством иллюстрируют общую идею статьи - относительную простоту программирования нестандартных HID-устройств средствами Delphi.

Шина USB (Universal Serial Bus – универсальная последовательная шина) появилась 15 января 1996 года при утверждении первого варианта стандарта фирмами – Intel, DEC, IBM, NEC, Northen Telecom и Compaq.

Основная цель стандарта, поставленная перед его разработчиками – создать возможность пользователям работать в режиме Plug&Play с периферийными устройствами. Это означает, что должно быть предусмотрено подключение устройства к работающему компьютеру, автоматическое распознавание его немедленно после подключения и последующей установки соответствующих драйверов. Кроме этого, желательно питание маломощных устройств подавать с самой шины. Скорость шины должна быть достаточной для подавляющего большинства периферийных устройств. Контроллер USB должен занимать только одно прерывание независимо от количества подключенных к шине устройств, то есть решить проблему нехватки ресурсов на внутренних шинах IBM PC совместимого компьютера.

Практически все поставленные задачи были решены в стандарте на USB и весной 1997 года стали появляться компьютеры, оборудованные разъемами для подключения USB устройств. Сейчас USB стала настолько активно внедряться производителями компьютерной периферии, что, например, в компьютере iMAC фирмы Apple Computers присутствует только USB в качестве внешней шины.

Возможности USB 1.0 следующие:

1. высокая скорость обмена данными (full-speed) – 12 Мбит /с;

2. максимальная длина кабеля для высокой скорости обмена – 5 метров;

3. низкая скорость обмена данными (low-speed) – 1,5 Мбит /с;

4. максимальная длина кабеля для низкой скорости обмена – 3 метра;

5. максимальное количество подключенных устройств – 127;

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

8. максимальный ток потребления на одно устройство – 500 мА.

Поэтому целесообразно подключать к USB 1.0 практически любые периферийные устройства, кроме цифровых видеокамер и высокоскоростных жестких дисков. Особенно удобен этот интерфейс для подключения часто подключаемых/отключаемых приборов, таких как цифровые фотокамеры.
Возможность использования только двух скоростей обмена данными ограничивает применяемость шины, но существенно уменьшает количество линий интерфейса и упрощает аппаратную реализацию.
Питание непосредственно от USB возможно только для устройств с малым потреблением, таких как клавиатуры, мыши, джойстики и т.п.

Сигналы USB передаются по 4-х проводному кабелю, схематично показанному на рисунке ниже:

Рисунок 2.6.1 – Сигнальные провода USB

Здесь GND – цепь общего провода для питания периферийных устройств, Vbus - +5 В также для цепей питания. Шина D+ предназначена для передачи данных по шине, а шина D- для приема данных.
Кабель для поддержки полной скорости шины (full-speed) выполняется как витая пара, защищается экраном и может также использоваться для работы в режиме минимальной скорости (low-speed). Кабель для работы только на минимальной скорости (например, для подключения мыши) может быть любым и неэкранированным.
Разъемы, используемые для подключения периферийных устройств, делятся на серии: разъемы серии «A» (вилка и розетка) предназначены только для подключения к источнику, например, компьютеру, разъемы серии «B» (вилка и розетка) только для подключения к периферийному устройству.

USB разъемы имеют следующую нумерацию контактов, показанную в таблице 2.6.1.

Таблица 2.6.1 – Назначение и маркировка контактов USB

В 1999 году тот же консорциум компьютерных компаний, который инициировал разработку первой версии стандарта на шину USB, начал активно разрабатывать версию 2.0 USB, которая отличается введением дополнительного высокоскоростного (Hi-speed) режима. Полоса пропускания шины увеличена в 40 раз, до 480 Мбит/с, что сделало возможным передачу видеоданных по USB.
Совместимость всей ранее выпущенной периферии и высокоскоростных кабелей полностью сохраняется. Контроллер стандарта 2.0 уже интегрирован в набор системной логики программируемых устройств (например, материнская плата персонального компьютера).

В 2008 году компаниями Intel, Microsoft, Hewlett-Packard, Texas Instruments, NEC и NXP Semiconductors создана спецификация стандарта USB 3.0. В спецификации USB 3.0 разъёмы и кабели обновлённого стандарта физически и функционально совместимы с USB 2.0, однако в дополнение к четырем линиям связи, добавлены ещё четыре. Тем не менее, новые контакты в разъёмах USB 3.0 расположены отдельно от старых на другом контактном ряду. Спецификация USB 3.0 повышает максимальную скорость передачи информации до 5 Гбит/с - что на порядок больше 480 Мбит/с, которые может обеспечить USB 2.0. Кроме того, увеличена максимальная сила тока с 500 мА до 900 мА на одно устройство, что позволяет питать некоторые устройства, требующие ранее отдельного блока питания.

Предположим, разработано устройство USB, с которым необходимо работать с помощью компьютера. Этого можно достигнуть минимум двумя способами:

1. разработка полнофункционального драйвера операционной системы;

2. использования интерфейса специального класса USB – устройств, называемых HID (Human Interface Device) устройствами.

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

Второй способ заключается в следующем. Существует поддерживаемый современными операционными системами интерфейс для устройств взаимодействия компьютера и человека или HID-устройств, таких как:

1. клавиатуры, мыши, джойстики;

2. различные датчики и считыватели;

3. игровые рулевое управление и педали;

4. кнопки, переключатели, регуляторы.

Любое такое устройство, если оно выполняет требования к HID-устройствам, будет автоматически распознано системой и не потребует написания специальных драйверов. Кроме того, их программирование, как правило, намного проще написания специализированного драйвера устройства. К сожалению, способ имеет существенный недостаток: скорость обмена информации с HID-устройством сильно ограничена и составляет максимум 64 кБ/с.

Принципиально на основе HID-технологии можно организовать взаимодействие с любым устройством, даже если оно не является в строгом смысле интерфейсным устройством человека и компьютера. Это позволяет отказаться от трудоемкой разработки уникального драйвера устройства и сэкономить время на разработку нового USB-устройства. На стороне хоста обменом с устройством будет руководить стандартный HID-драйвер, включенный в поставку операционной системы. Нужно лишь выполнить со стороны устройства минимальные требования USB-HID протокола.

Стоит отметить что, многие USB-приборы, с первого взгляда не попадающие под определение устройств взаимодействия с человеком, логичнее все же реализовать как HID-устройства. Такое явление часто встречается в области производственного оборудования, которая последнее время переживает массовое внедрение USB-технологий. К примеру, рассмотрим лабораторный источник питания с возможностью задания параметров его выходных сигналов с компьютера с помощью USB-интерфейса. Непосредственно источник питания без сомнений не является средством взаимодействия с человеком. Однако, в данном случае функции, реализуемые посредством USB-подключения, дублируют клавиатуру, регуляторы и индикаторы, установленные на самом приборе. А эти органы управления как раз попадают под определение HID. Соответственно блок питания с этими USB-функциями логичнее всего организовать как HID-устройство.

В рассмотренном примере для нормальной работы достаточно будет небольшой скорости передачи данных, в других же случаях приборы могут быть весьма требовательны к скорости обмена. Низкая скорость передачи является главным ограничением HID-варианта построения устройства, что в сравнении с 12 Мбит/сек полной скорости USB 1.0-шины выглядит большим минусом HID-технологии в вопросе выбора конкретной USB-реализации. Однако для многих задач коммуникации указанной скорости вполне хватает и HID-архитектура как специализированный инструмент занимает достойное место среди способов организации обмена данными.

HID-устройства бывают двух типов: участвующие (загрузочные) и неучаствующие в начальной загрузке компьютера. Наиболее ярким примером загрузочного USB-HID устройства является клавиатура, работа которой начинается со стартом компьютера.

При разработке HID-устройства необходимо обеспечить следующие требования, налагаемые спецификацией:

1. полноскоростное HID-устройство может передавать 64000 байт каждую секунду или по 64 байта каждые 1 мс; низкоскоростное HID-устройство имеет возможность передать вплоть до 800 байт в секунду или по 8 байт каждые 10 мс.

2. HID-устройство может назначить частоту своего опроса для определения того, есть ли у него свежие данные для передачи.

3. Обмен данными с HID-устройством осуществляется посредством специальной структуры, называемой репортом (Report). Каждый определенный репорт может содержать до 65535 байт данных. Структура репорта имеет весьма гибкую организацию, позволяющую описать любой формат передачи данных. Для того чтобы конкретный формат репорта стал известен хосту микроконтроллер должен содержать специальное описание – дескриптор репорта.

Реализуется USB взаимодействие непосредственно на микроконтроллере несколькими способами:

1. использованием контроллера с аппаратной поддержкой, например AT90USB*, фирмы atmega;

2. использованием программной эмуляции usb-интерфейса на любом микроконтроллере.

Для программной реализации в настоящее время существует ряд готовых решения под различные семейства микроконтроллеров. Для AVR микроконтроллеров, например, Atmega8 возможно использовать следующие свободные библиотеки на языке Си:

Обе достаточно простые в использовании, обеспечивают полную эмуляция USB 1.1 low-speed устройств за исключением обработки ошибок связи и электрических характеристик и запускаются практически на всех AVR контроллерах с минимум 2 килобайтами flash-памяти, 128 байтами RAM и частотой от 12 до 20 МГц.

Для написания приложений с поддержкой Windows USB HID устройств требуются заголовочные файлы hid*, входящие в состав WDK (Windows Driver Kit), или можно использовать свободно-распространяемую библиотеку hidlibrary или другую аналогичную.

Таким образом, в общем случае программирование USB достаточно сложная задача, требующая специального микроконтроллера с аппаратной поддержкой и написания драйвера операционной системы. Однако в практике при разработке устройств можно использовать значительно более просто интерфейс HID – устройств, поддержка которого реализована на уровне стандартного драйвера системы, а программирование упрощается использованием существующих библиотек функций.

Контрольные вопросы

  1. В чем отличие провода D- и GND в USB? Почему нельзя использовать один общий провод для питания и сигнала?
  2. Сколько режимов скорости работы USB существует на сегодняшний день (включая версию 3.0)?
  3. Что такое HID-устройство? Почему для их работы в современных ОС не требуется написание драйверов?
  4. Можно ли реалировать USB устройства с помощью микропроцессора, неимеющего встроенной поддержки интерфейса?
  5. Какие основные отличия USB 3.0 от предыдущих версий?