• Работа usb порта интерфейс программирования. Практическое использование интерфейса USB в PIC контроллерах

    Но ведь мало только физически подсоединить устройство к компьютеру, нужно еще и наладить обмен данными между ними. Как же выбрать порт и организовать подключение? Несколько лет назад стандартным решением было использование 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


    рис.1 Иллюстрация работы Android устройства в режимах USB Host и Accessory (рисунок с сайта http://developer.android.com)

    Отметим, что использование USB - не единственный способ связи с тем же самодельным устройством. Android позволяет использовать еще , NFC, Wi-Fi P2P, SIP, а также стандартное сетевое подключение . Так что в арсенале разработчика достаточно возможностей для осуществления своих самых смелых замыслов.

    Другим распространенным вариантом связи с различными устройствами до сих пор является использование переходника USB-COM. Материал в сети по применению переходника USB-COM в Android есть - см., например, . Популярность такого подключения обусловлена наличием большого количества уже разработанных с использованием различных микроконтроллеров устройств, связь с которыми осуществляется с помощью COM-порта (последовательного порта), что лет 10 назад являлось почти стандартным способом передать данные от компьютера к самодельной «железке».

    В сравнении с COM-портом, использование USB позволяет существенно повысить скорость передачи данных и сделать этот процесс удобным для пользователя. Cкорость передачи, которая даже в случае низкоскоростных устройств (клавиатуры, мыши, джойстики), составляет 10-1500 Кбит/c, простота и невысокая стоимость кабельной системы и подключений, самоидентификация устройств с автоматическим конфигурированием, скрытие подробностей электрического подключения от конечного пользователя (плюс возможность отключения кабеля без выключения устройств), контроль ошибок и их восстановление на уровне протокола - вот неоспоримые преимущества данной технологии (см. , с.12).

    Вообще, говоря об использовании USB для передачи данных, нелишним будет упомянуть книгу П.Агурова «Интерфейс USB» . Она, хотя часто критикуется в сети и выпущена последний раз в 2006 году, не раз помогла найти верное решение при поиске информации по различным аспектам применения этой технологии. В книге рассмотрены вопросы: от выбора микросхемы и схемотехники для контроллера до написания программы микроконтроллера и примеров программирования передачи данных по протоколу USB со стороны компьютера. Нельзя не указать и "первоисточник" данных по этому вопросу - сайт некоммерческой организации USB IF (USB Implementers Forum), занимающейся разработкой спецификаций этого интерфейса - , правда данный материал на английском языке. Однако именно там вы найдете исчерпывающие сведения об устройстве интерфейса USB. Есть неплохой перевод частей спецификации - . Интересующимся программными решениями со стороны микроконтроллера также можно посмотреть ссылку .

    Данная статья адресована прежде всего тем, у кого есть какое-либо электронное устройство (разработанное самостоятельно или кем-то еще), протокол обмена данными с которым хорошо известен (например, уже есть программа, работающая с этим устройством в Windows/Linux) и хотелось бы иметь программу, работающую с ним в Android.

    Немного о классах USB-устройств

    Необходимо отметить, что разработка программного обеспечения для обмена данными с конкретным устройством сильно зависит от его реализации на уровне микроконтроллера. Привести примеры программ связи для всех типов USB-устройств в рамках одной статьи, по понятным причинам, невозможно (начальные сведения о программировании различных типов устройств можно почерпнуть в ). Однако, мы ограничимся тем, что приведем код, реализующий поиск устройства и доступ к его контрольным точкам для обмена информацией. Также разберем отправку данных на примере одного из типов USB-устройств, а именно, класса устройств HID (human interface device - класс устройств для взаимодействия с человеком). Этот класс включает в себя «медленные» устройства, такие как клавиатура, мышь, джойстик и примеров его реализации с помощью различных микроконтроллеров в сети достаточно (есть, например, и в ).

    Почему именно класс HID так полюбился изготовителям различных самодельных устройств? Процитируем Википедию : «Помимо детальных спецификаций классических устройств ввода (типа клавиатур и мышек) стандарт HID определяет особый класс устройств без детальных спецификаций. Этот класс именуется USB HID Consumer Control и представляет собой по сути нерегламентированный канал связи с устройством. При этом устройство пользуется теми же стандартными для операционной системы драйверами что и мышка с клавиатурой. Таким образом, можно создать USB устройство которое не требует создания и инсталляции специальных драйверов в большинстве распространенных компьютерных операционных систем». Остается добавить только, что работает эта спецификация и в ОС Android (не исключая прошивок CyanogenMod).

    Одним из вариантов обмена данными с HID-устройством является передача по прерываниям (interrupt transfer), которая используется в том случае, когда необходимо передать пакеты данных небольшого размера (максимальный размер пакета зависит от скорости передачи и составляет от 64 до 1024 байт) через заданный временной интервал. Пакет для передачи называется репортом (англ. - report, см. с.71, 95). Такой длины репорта обычно вполне хватает для обмена информацией с самодельным устройством, 64 байта информации в одном пакете, например, - это довольно много для контроллера, ведь для передачи состояний светодиода или простейшего датчика достаточно 1 бита информации.

    Необходимые инструменты

    Итак, нам понадобятся - планшет или телефон с Android версии не ниже 3.1. Здесь необходимо отметить, что вышеуказанный USB Host API полностью реализован не на всех мобильных устройствах (об этом упоминается и на сайте developer.android.com, см. ссылку ). В некоторых планшетах/телефонах разъем USB используется только для зарядки и связи с персональным компьютером. Еще раз отправлю читателя к списку мобильных устройств, пригодных или непригодных для наших опытов (см. ).

    Понадобится также какое-либо USB-устройство (для первых опытов будет достаточно обычного USB-флеш-накопителя), переходник OTG (On-The-Go - см. рис. 2) и/или шнур USB для связи с устройством. В Википедии по поводу OTG говорится: «При подключении через USB OTG ранг устройства (ведущий или ведомый) определяется наличием или отсутствием перемычки между контактами 4 и 5 в штекере соединительного кабеля. В USB OTG кабеле такая перемычка устанавливается лишь в одном из двух разъемов (см. ).» Соответственно, нам необходима такая перемычка со стороны мобильного устройства.


    Рис.2 Различия в схеме обычного USB-кабеля и OTG-кабеля (рисунок с сайта http://tech.firstpost.com)

    Такой OTG-кабель для Вашего устройства можно спаять и самостоятельно. Для этого необходимо купить в радиомагазине подходящий разъем, плюс автор, например, использовал старый кабель от переносного жесткого диска:

    Неплохим подспорьем в работе будет также программа USB Device Info, установленная из хранилища Google Play Market. Программа умеет определять подключенные к USB-разъему планшета/телефона устройства как с помощью Java API так и с помощью ядра Linux. То есть, если Ваше устройство не определилось с помощью Java USB Host API в USB Device Info, то, с большой вероятностью, тщетно будет использовать для этого мобильного устройства какую-либо (в том числе и свою) Android-программу, написанную с помощью Java и USB Host API.

    Иногда, также, очень полезной бывает информация, выводимая командой lsusb операционной системы Linux. С ключами -v и -d lsusb выводит о USB-устройстве все, или почти все, что необходимо разработчику программного обеспечения для устройств этого класса (см. рис.3).


    Рис.3 Пример вывода команд lsusb и lsusb -v -d

    Далее, необходим компьютер с установленным Android SDK и интегрированной средой разработки (IDE) Eclipse с плагином ADT (хотя можно обойтись и только SDK). Как создать и установить приложение для Android можно посмотреть, например, в , или в сети Интернет.

    Ну и, конечно, необходимо хотя бы а также желание добиться результата, без него никак! Отмечу, что на выяснение некоторых технических вопросов применения USB в Android автором, потребовались недели кропотливого поиска информации.

    Классы Java для работы с USB в Android API

    Итак, как говорится на сайте разработчиков USB Host API для Android (см. ) - «прежде чем начать, важно понять какие классы вы будете использовать в работе». В таблице 1 приведено описание важнейших классов для работы с USB Host API (попытка перевода информации с http://developer.android.com).

    Таблица 1. Описание классов для работы с USB в Android

    Название класса Описание
    UsbManager Allows you to enumerate and communicate with connected USB devices.
    Позволяет определять подключенное USB-устройство и обмениваться с ним данными.
    UsbDevice Represents a connected USB device and contains methods to access its identifying information, interfaces, and endpoints.
    Представляет подключенное USB-устройство и содержит методы для доступа к его идентификационной информации, интерфейсам, и конечным точкам.
    UsbInterface Represents an interface of a USB device, which defines a set of functionality for the device. A device can have one or more interfaces on which to communicate on.
    Представляет «интерфейс» USB-устройства, который определяет набор функций для данного устройства. Одно устройство может иметь один или несколько интерфейсов для обмена информацией.
    UsbEndpoint Represents an interface endpoint, which is a communication channel for this interface. An interface can have one or more endpoints, and usually has input and output endpoints for two-way communication with the device.
    Представляет «конечную точку» интерфейса, которая и является каналом связи для этого интерфейса. Интерфейс может иметь одну и более конечных точек, и обычно имеет конечные точки для получения информации и для ее передачи.
    UsbDeviceConnection Represents a connection to the device, which transfers data on endpoints. This class allows you to send data back and forth sychronously or asynchronously.
    Представляет «подключение» к данному устройству. Необходимо для передачи данных в конечную точку. Этот класс позволяет получать данные или передавать синхронно или асинхронно.
    UsbRequest Represents an asynchronous request to communicate with a device through a UsbDeviceConnection.
    Представляет асинхронный запрос на обмен данными с устройством через UsbDeviceConnection.
    UsbConstants Defines USB constants that correspond to definitions in linux/usb/ch9.h of the Linux kernel..
    Определяет константы, которые соответствуют определениям в linux/usb/ch9.h ядра Linux.

    Практически во всех случаях применения USB Host API программист использует эти классы в своей работе. Алгоритм их применения выглядит примерно так: определяем устройства (цель - программный доступ к классу UsbDevice), подключенные к хосту (мобильному устройству), с помощью UsbManager. Когда программный доступ устройству получен, необходимо определить соответствующие UsbInterface и UsbEndpoint для общения с ним. Как только вы получили в свое распоряжение конечную точку, откройте UsbDeviceConnection, чтобы общаться с USB-устройством. Если конечная точка работает в режиме асинхронной передачи, используем класс UsbRequest.

    Давайте попробуем со всем этим разобраться создав простое приложение, которое, используя этот API, определит подключенное к хосту с ОС Android устройство и выведет о нем некоторую информацию на экран телефона или планшета.

    Создаем проект

    В Eclipse проект создается с помощью пунктов меню File->New->Android Application Project. Заметим также, что код, приведенный ниже заимствован из приложений-примеров, поставляемых с Android SDK (папка android sdk samples/android-N(API Level)/USB) речь идет о программе управления USB-игрушкой Missile Launcher (см. рис. 4) Примеры приложений загружаются через Android SDK Manager (нужно отметить пункт - Samples for SDK ). В листингах, приведенных ниже, примеры кода снабжены комментариями, которые объясняют суть происходяшего.


    Рис.4 Забавная игрушка "Ракетозапускалка"

    Создавая проект не забудьте отметить нужный API Level в опции Minimum Requared SDK (API Level 12, соответствующий версии Android 3.1 /Honeycomb/, или выше). В проекте будет очень простой интерфейс пользователя - главное окно (Activity) и TextView для вывода информации. Подобный проект подробно рассмотрен в .

    В созданном автоматически классе для Activity нашего проекта необходимо определить следующие экземпляры классов для работы с USB:

    private TextView lgView;
    private UsbManager mUsbManager;
    private UsbDevice mDevice;
    private UsbDeviceConnection mConnection;
    private UsbEndpoint mEndpointIntr;

    LgView = (TextView) findViewById(R.id .logTextView ) ;

    и получаем доступ к классу UsbManager

    MUsbManager = (UsbManager) getSystemService(Context .USB_SERVICE ) ;

    Создадим еще обработчик события onResume(). Добьемся цели - чтобы информация о подключенных устройствах обновлялась при активизации окна нашего приложения (см. Листинг 1).

    Листинг 1. Обработчик события onResume()

    public void onResume() {
    super .onResume () ;

    //заполняем контейнер списком устройств
    HashMap< String , UsbDevice> deviceList = mUsbManager.getDeviceList () ;
    Iterator< UsbDevice> deviceIterator = deviceList.values () .iterator () ;

    lgView.setText ( "Devices Count:" + deviceList.size () ) ;

    while (deviceIterator.hasNext () ) {
    UsbDevice device = (UsbDevice) deviceIterator.next () ;

    //пример определения ProductID устройства
    \n " + "Device ProductID: " + device.getProductId () ) ;
    }
    //определяем намерение, описанное в фильтре
    // намерений AndroidManifest.xml
    Intent intent = getIntent() ;
    lgView.setText ( lgView.getText () + "\n " + "intent: " + intent) ;
    String action = intent.getAction () ;

    //если устройство подключено, передаем ссылку в
    //в функцию setDevice()
    UsbDevice device = (UsbDevice) intent.getParcelableExtra (UsbManager.EXTRA_DEVICE ) ;
    if (UsbManager.ACTION_USB_DEVICE_ATTACHED .equals (action) ) {
    setDevice(device) ;
    lgView.setText ( lgView.getText () + "\n " + "UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action) is TRUE" ) ;
    } else if (UsbManager.ACTION_USB_DEVICE_DETACHED .equals (action) ) {
    if (mDevice != null && mDevice.equals (device) ) {
    setDevice(null ) ;
    lgView.setText ( lgView.getText () + "\n " + "UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action) is TRUE" ) ;
    }
    }

    Далее, для Activity создадим функцию setDevice(), необходимую для работы с нашим устройством (см. Листинг 2). В обработчике onResume() и в функции setDevice() мы в точности выполнили алгоритм применения USB Host API, описанный в предыдущем разделе.

    Листинг 2. Функция setDevice()

    private void setDevice(UsbDevice device) {
    lgView.setText ( lgView.getText () + "\n " + "setDevice " + device) ;

    //определяем доступные интерфейсы устройства
    if (device.getInterfaceCount () != 1 ) {

    LgView.setText ( lgView.getText () + "\n " + "could not find interface" ) ;
    return ;
    }
    UsbInterface intf = device.getInterface (0 ) ;

    //определяем конечные точки устройства
    if (intf.getEndpointCount () == 0 ) {

    LgView.setText ( lgView.getText () + "\n " + "could not find endpoint" ) ;
    return ;
    } else {
    lgView.setText ( lgView.getText () + "\n " + "Endpoints Count: " + intf.getEndpointCount () ) ;
    }

    UsbEndpoint epIN = null ;
    UsbEndpoint epOUT = null ;

    //ищем конечные точки для передачи по прерываниям
    for (int i = 0 ; i < intf.getEndpointCount () ; i++ ) {
    if (intf.getEndpoint (i) .getType () == UsbConstants.USB_ENDPOINT_XFER_INT ) {
    if (intf.getEndpoint (i) .getDirection () == UsbConstants.USB_DIR_IN ) {
    epIN = intf.getEndpoint (i) ;
    lgView.setText ( lgView.getText () + "\n " + "IN endpoint: " + intf.getEndpoint (i) ) ;
    }
    else {
    epOUT = intf.getEndpoint (i) ;
    lgView.setText ( lgView.getText () + "\n " + "OUT endpoint: " + intf.getEndpoint (i) ) ;
    }
    } else { lgView.setText ( lgView.getText () + "\n " + "no endpoints for INTERRUPT_TRANSFER" ) ; }
    }

    MDevice = device;
    mEndpointIntr = epOUT;

    //открываем устройство для передачи данных
    if (device != null ) {
    UsbDeviceConnection connection = mUsbManager.openDevice (device) ;
    if (connection != null && connection.claimInterface (intf, true ) ) {

    LgView.setText ( lgView.getText () + "\n " + "open device SUCCESS!" ) ;
    mConnection = connection;

    } else {

    LgView.setText ( lgView.getText () + "\n " + "open device FAIL!" ) ;
    mConnection = null ;
    }
    }
    }
    }

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

    Листинг 3. Пример кода для отправки данных устройству

    //определение размера буфера для отправки
    //исходя из максимального размера пакета
    int bufferDataLength = mEndpointIntr.getMaxPacketSize () ;

    lgView.setText ( lgView.getText () + "\n " + mEndpointIntr.getMaxPacketSize () ) ;

    ByteBuffer buffer = ByteBuffer.allocate (bufferDataLength + 1 ) ;

    UsbRequest request = new UsbRequest() ;

    buffer.put (message) ;

    request.initialize (mConnection, mEndpointIntr) ;

    request.queue (buffer, bufferDataLength) ;

    if (request.equals (mConnection.requestWait () ) )

    //отправка прошла успешно
    //lgView.setText(lgView.getText() + "\n" + "sending CLEAR!!!");

    catch (Exception ex)

    //что-то не так...
    //lgView.setText(lgView.getText() + "\n" + "sending not clear...");

    Фильтрация устройств в AndroidManifest.xml

    Хотя в нашем приложении нет нужды в поиске конкретного устройства с известными VID (Vendor-ID) и PID (Product-ID), инженеры Google не приводят примеров приложений без секции intent-filter в манифест файле, и автору не удалось добиться работы программы без фильтрации устройств в AndroidManifest.xml .

    Напомню, что Vendor-ID и Product-ID это уникальные идентификаторы USB-устройств. То есть, используя фильтрацию, можно создать приложение, которое взаимодействует лишь с определенным устройством или каким-то классом устройств. Отметим, что производители устройств должны согласовать эти номера с организацией USB IF.

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

    Листинг 4. Файл AndroidManifest.xml


    " > http://schemas.android.com/apk/res/android"
    > package="ru.learn2prog.usbhostexample"
    android:versionCode="1"
    android:versionName="1.0" >


    android:minSdkVersion ="12"
    android:targetSdkVersion ="14" />


    android:allowBackup ="true"
    android:icon ="@drawable/ic_launcher"
    android:label ="@string/app_name"
    android:theme ="@style/AppTheme" >

    android:name ="ru.learn2prog.usbhostexample.MainActivity"
    android:label ="@string/app_name" >
    >

    "android.intent.category.DEFAULT" />

    "android.intent.category.LAUNCHER" />

    >

    >

    >
    "android.hardware.usb.action.USB_DEVICE_ATTACHED"
    android:resource ="@xml/device_filter" />
    >
    >

    >

    Листинг 5. Файл фильтра device_filter.xml (каталог /res/xml)

    >

    >

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

    Литература/Ссылки: 11.
    12.
    13. http://developer.android.com/guide/topics/connectivity/usb/host.html - обзор классов, необходимых для работы с USB в Android
    14. ссылка на исходники приложения