Что такое usb девайс
Содержание
Комментарии ( 33 )
емнип, с интервалом в 1 мс, но «низкоскоростные» устройства могут опрашиваться не каждый раз, а, например раз за 10 циклов опроса
автор молодец! давно хотел освоить УСБ но никак не доходили руки да и не понимал ничего. тут все описано просто, красиво и понятно. так держать!
В данном цикле статей будет рассмотрен под разными углами интерфейс USB (USB 2.0) Попробуем разобраться, как он работает и закрепить полученные знания практически. «Копать» мы будем достаточно глубоко, не коснемся только физического уровня передачи данных (вернее коснемся вскользь). Физический уровень возьмет на себя соответствующий периферийный модуль МК.
Все примеры, которые я буду приводить, будут привязаны к линейке МК AT91SAM7S. Так как эта линейка МК не очень популярна в Сообществе, я постараюсь акцентировать внимание на работе самого интерфейса и по минимуму затрону специфические для этого МК особенности реализации.
Примеры будут базироваться на «глубоко модернизированном» и достаточно низкоуровневом примере реализации USB от Atmel. Готовые библиотеки рассматривать не будем. Не по тому, что это плохо, просто наша цель разобраться — как работает интерфейс.
В качестве практического задания – давайте поставим целью создать CDC-ACM устройство. На практике, за сокращением CDC-ACM стоит «обыкновенный» виртуальный СОМ-порт. С терминологией разберемся позже, пока скажем так: на уровне ОС устройство будет автоматически распознаваться как последовательный интерфейс (COM-порт в Win, /dev/ttyS в Linux и т. д.).
Общие сведения.
USB –последовательный интерфейс, используемый для подключения периферийных устройств. Соответственно, существуют понятие «главное устройство» (хост, он управляет обменом данными через интерфейс, выступает инициатором обмена) и «периферийное устройство» (клиент, в процессе обмена данными «подчиняется» хосту).
Логика работы у хоста и клиента принципиально отличается, соответственно нельзя напрямую соединять устройства «хост – хост» и «клиент – клиент».
Есть специальные устройства – хабы, которые подключаются в качестве клиента к одному хосту и, в тоже время, выступают хостом для других периферийных устройств. Хабы используют для «разветвления» шины USB.
Полагаю, изложенные факты общеизвестны, двигаемся далее.
Физический уровень.
Физически интерфейс USB использует 4 провода: «земля (GND)», «+5В (VBUS)», «D+», «D-». Первые два могут использоваться для питания периферийного устройства (максимальный ток 500 мА). Два последних служат для передачи данных (обозначение D+ и D- условны, с электрическими потенциалами это никак не связанно).
Как я уже сказал, физическую передачу данных через D+ и D- нам обеспечит USB модуль МК.
Нам нужно знать следующее:
1. Питание на периферийное устройство подается сразу после подключения к USB разъему хоста. Сам разъем сконструирован таким образом, что первыми входят в «зацепление» контакты «GND» и «VBUS», только потом «D+» и «D-».
2. Подключение устройства к USB разъему хоста не означает, что хост сразу определит подключение нового устройства. Если не вдаваться в подробности, подключение/отключение устройства хост определяет по наличию вешней подтяжки на линиях D+ и D-. Такая формулировка очень упрощена, детально ознакомиться с вопросом можно в разделе 7.1.7.3 официальной спецификации USB 2.0.
В нашем случае, для того чтобы «заявить о себе» нужно подтянуть линию D+ посредством сопротивления 1.5 кОм к напряжению 3.3 вольта. Если мы уберем данную подтяжку – хост определит отключение устройства.
Подтяжку можно сделать постоянной (в таком случае хост будет определять подключение / отключение устройства одновременно с подключением / отключением устройства к разъему USB), либо управлять подтяжкой через ключ, дергая ногой МК (тогда наше устройство сможет самостоятельно подключатся и отключатся от хоста).
Логический уровень
На логическом уровне, обмен данными происходит через некоторые логические, виртуальные каналы внутри одного физического USB интерфейса. Такие каналы называют «Конечными точками» (EndPoints).
Конечные точки (каналы) бывают 4 видов:
Control – данный тип канала используется хостом для управления периферийным устройством. Хотя иногда данный тип канала используется для передачи данных.
Bulk — данный тип канала используется для обмена данными. Гарантирование целостности данных и гарантированная доставка данных для данного типа канала реализована «в железе». Однако скорость передачи данных по такому каналу ограничена.
Isochronous — данный тип канала в основном используется для обмена потоковыми данными. Целостность и доставка данных не контролируются, зато скорость значительно выше чем для Bulk каналов.
Interrupt – используются для реализации подобия «прерываний». Такие «прерывания» являются логическими, и никак напрямую не связанны с аппаратными прерываниями МК или прерываниями ОС.
Минимальная реализация USB устройства требует наличие всего одного Control канала (так называемая «нулевая конечная точка»). Остальные типы каналов, как и их количество определяет разработчик устройства исходя из функций устройства.
Однако, существуют некоторые стандартизированные классы USB устройств. Для каждого такого класса количество каналов, их типы и назначение установлено стандартом для данного класса устройств.
Мы стремимся создать устройство класса CDC (communications device class). Использование стандарта, в данном случае, избавит нас от необходимости писать драйвер для ОС. Как правило, драйвера для стандартных классов устройств уже «вшиты» во все популярные ОС.
Детально ознакомляться с типами каналов будем по ходу реализации нашего устройства. Забегая наперед, скажу, что в нашем устройстве будет 3 канала. Control канал для управления и два Bulk канала для предачи данных по направлению «ПК-МК» и, соответственно «МК-ПК».
Первая — вводная статья получилась слишком теоретической.
В следующей статье мы поговорим о дескрипторах USB устройства и рассмотрим процедуру инициализации устройства (запрос дескрипторов хостом и т. д.). Увы, но опять будет много теории, запаситесь терпением. :) Ничего, нам осталось «пережевать» дескрипторы устройств, после чего появятся примеры кода.
Итак, нам осталось разобраться с процессом обработки стандартных запросов USB и с дескрипторами. Давайте сначала разберемся с теорией, а потом подробно разберем пример обработки конкретного запроса.
Обработка запросов.
Процесс обработки запроса состоит из трех фаз (SETUP, DATA, STATUS), причем фаза DATA является опциональной.
Как мы помним из предыдущей статьи, для передачи запросов хост использует специальный TOKEN пакет — TOKEN SETUP. Собственно говоря, первая фаза состоит из того, что хост посылает TOKEN SETUP, затем посылает пакет данных (8 байт) который содержит запрос. Устройство подтверждает получение запроса ACK пакетом. Структуру запроса мы рассмотрим ниже, пока перейдем к следующей фазе – фазе обмена данными.
Дело в том, что некоторые типы запросов предполагают передачу дополнительных данных, как от хоста к устройству (передача дополнительных параметров запроса) так и от устройства к хосту (получение хостом ответа на запрос). Этот обмен и составляет фазу обмена данными.
Хост, отравив запрос в SETUP фазе, знает тип запроса и, соответственно, знает: нужна ли для данного типа запроса фаза обмена данными и в какую сторону будет происходить обмен.
Если запрос предполагает передачу дополнительных параметров — хост отправляет TOKEN OUT и пакет данных содержащий дополнительные параметры запроса. Устройство подтверждает получение пакета данных, после чего хост может послать следующий пакет данных и т. д.
Соответственно, если запрос предполагает получение ответа от устройства, хост посылает TOKEN IN и ожидает пакет данных от устройства.
Последняя (STATUS) фаза нужна для подтверждения корректности обработки всего запроса. На данной фазе устройство или хост просто посылает пакет данных нулевой длины, что свидетельствует об успешной обработке запроса на логическом уровне. Если запрос предполагал получение ответа от устройства – то данный пакет посылает хост, подтверждая, что ответ получен/обработан. В другом случае – пакет нулевой длины шлет устройство, подтверждая, что запрос (запрос и дополнительные параметры) получены и обработаны.
Если что-то пошло не так (например, мы получили запрос который не умеем обрабатывать), устройство может послать STALL пакет, что свидетельствует об ошибке на логическом уровне. Но хост расценит это как фатальную ошибку т. к. стандартные запросы должны всегда корректно обрабатывается всеми USB устройствами.
Теперь заглянем «внутрь» запроса (8 байт данных полученных устройством в SETUP фазе). Запрос состоит из следующих полей:
bmRequestType — 1 байт
bRequest – 1 байт
wValue – 2 байта, WORD
wIndex – 2 байта, WORD
wLength – 2 байта, WORD
bmRequestType – битовое поле, которое содержит характеристики запроса:
Бит 7: Направление передачи данных в DATA фазе:
0 = от хоста к устройству
1 = от устройства к хосту
Биты 6. 5: Тип запроса
0 = стандартный запрос USB
1 = стандартный запрос для определенного класса устройств USB
2 = пользовательский запрос
3 = зарезервировано
Биты 4. 0: Кому адресован запрос
0 = устройству
1 = интерфейсу
2 = конечной точке
3 = другое
4. 31 = зарезервировано
bRequest – уникальный код запроса (например, 0 = GET_STATUS, 5 = SET_ADDRESS, 6 = GET_DESCRIPTOR и т. д.)
Здесь следует пояснить, зачем нужны биты 4..0 поля bmRequestType. Например, для получения статуса хост посылает запрос GET_STATUS (bRequest = 0). Значение бит 4. 0 поля bmRequestType определяет, статус чего именно хочет получить хост: 0 – статус устройства, 1 – статус интерфейса, 2 – статус контрольной точки и т. д.). Таким образом, «тип запроса» определяется битами 4..0 поля bmRequestType и полем bRequest.
wValue – данное поле может использоваться для передачи параметров запроса. Например, для запроса SET_ADDRESS данное поле содержит адрес, который нужно присвоить устройству. Если параметры запроса не помещаются в 2 байта wValue, то хост их передает в DATA фазе.
wIndex – значение данного поля зависит от типа запроса. Например, для запроса GET_STATUS к конечной точке, данное поле содержит индекс конечной точки, статус которой хост хочет получить.
wLength – данное поле содержит размер данных, которые будут переданы хостом в DATA фазе либо которые хост ожидает получить в DATA фазе.
Для примера, рассмотрим алгоритм обработки запроса GET_DESCRIPTOR.
1. Хост посылает устройству запрос:
bmRequestType = 0x80
bRequest = 6 (GET_DESCRIPTOR)
wValue = 0x100 (тип дескриптора, который хост хочет получить, в данном случае дескриптор устройства)
wIndex = 0 (в данном случае параметр не используется)
wLength = 18 (в ответ хост хочет получить 18 байт)
Из запроса видно, что хост хочет получить дескриптор нашего устройства и что за SETUP фазой предполагается DATA фаза «от устройства к хосту».
2. Устройство посылает хосту 18 байт дескриптора (DATA фаза).
3. Хост подтверждает успешное завершение обработки запроса, отправив устройству пакет данных нулевой длины (STATUS фаза).
Будем считать, что с обработкой запросов мы разобрались. Все запросы подробно разбирать мы не будем, т. к. это очень объемный материал. Детально все типы стандартных запросов описаны в разделе 9.3 официальной спецификации.
Касательно нашего CDC устройства — помимо стандартных запросов USB, для нашего класса устройств предусмотрено несколько дополнительных запросов (SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE). Эти запросы предназначены для установки параметров (Baudrate, Stop Bits, Parity, Data bits) нашего виртуального COM-порта. В нашей реализации эти параметры нам не нужны, но обрабатывать эти запросы мы обязаны, поэтому реализуем обработку в виде «заглушек».
Дескрипторы
Теперь поговорим о дескрипторах.
Стандартом определены следующие типы дескрипторов:
— Дескрипторы устройства
— Дескрипторы конфигурации
— Дескрипторы интерфейса
— Дескрипторы конечной точки
— Строковые дескрипторы
Дескриптор устройства всегда один, он содержит базовую информацию об устройстве (код производителя, код устройства, класс устройства и т. д.). Мы позже детально разберем данный дескриптор на примере нашего устройства.
Дескрипторы конфигурации описывают конфигурации нашего устройства.
Здесь остановимся немного подробнее. Дело в том, что устройство может поддерживать несколько альтернативных конфигураций. Например, в конфигурации «1» устройство питается от интерфейса USB, а в конфигурации «2» – от внешнего источника. Или в конфигурации «1» устройство для обмена данными с хостом использует дополнительные контрольные точки типа bulk, а в конфигурации «2» – весь обмен идет через «нулевую конечную точку».
Для каждой из конфигураций устройство хранит свой дескриптор конфигурации. Хост получает по запросу дескрипторы всех конфигураций и выбирает одну из возможных конфигураций (логика выбора «рабочей» конфигурации из возможных заложена в драйвере устройства). После этого, хост назначает устройству номер текущей конфигурации (отправив стандартный запрос SET_CONFIGURATION) и дальнейшая работа устройства происходит в соответствии с выбранной хостом конфигурацией.
Для каждой конфигурации устройства определен один или несколько «интерфейсов». Интерфейс определяет, какие контрольные точки будут использоваться для обмена данными между хостом и устройством. Эта информация и есть «дескриптор интерфейса».
Информация о каждой конечной точке интерфейса называется «дескриптор конечной точки». Для каждой конечной точки дескриптор описывает тип конечной точки, ее параметры (такие как максимальный размер буфера обмена и т. д.)
Каждый дескриптор конфигурации содержит в себе дескрипторы интерфейса, а каждый дескриптор интерфейса содержит дескрипторы конечных точек.
Строковые дескрипторы опциональны, они позволяют получить хосту, в виде UNICODE строки, название устройства, название производителя устройства, серийный номер устройства.
Для примера, рассмотрим «дескриптор устройства», пример которого уже приводился в одной из статей.
Итак, в дескрипторе содержится следующая ключевая информация:
1. Устройство поддерживает версию стандарта 2.0
2. Устройство относится к классу CDC
3. Код производителя 0x03EB (Atmel)
4. Код продукта (в рамках производителя) 0x6127
5. Код ревизии устройства 0x0110
6. Устройство поддерживает одну конфигурацию
Компания Atmel позволяет использовать свой код производителя (VID) при создании USB устройств на базе ее продукции, правда с небольшими оговорками. Остальные параметры (Код продукта, Код ревизии устройства) выбраны «с потолка» :)
Комбинация VID/PID используется ОС для идентификации устройства и поиска «подходящего» драйвера. В некоторых случаях, для поиска драйвера используется информация о классе устройства (например, для HID и MSD устройств).
Описывать «побитно» все дескрипторы мы не будем, эта информация подробно описана в разделе 9.6 спецификации.
Теперь фрагмент кода — реализации данного уровня логики USB.
Эта статья завершает цикл.
Как и обещал – выкладываю исходные коды примера реализации (не стоит забывать, что это лишь пример, реализация очень упрощена). Для демонстрации работы стека в main.c реализована простая эхо-отвечалка, все данные полученные от ПК устройство отправляет обратно :)
Вместе с исходниками лежит файл USBCDC.inf – этот файл нужен ОС Windows для того, чтобы связать VID/PID нашего устройства со стандартным драйвером виртуального USB COM-порта (usbser.sys)
Логические спецификации
Синхронизация данных в неизохронных передачах
Спецификация USB определяет простой протокол для обеспечения, синхронизация данных через многократные пакеты для неизохронных передач (вспомните, что изохронные передачи не поддерживают восстановление после ошибки или повторную попытку). Протокол реализован посредством бита переключателя данных и в узле и в конечной точке, синхронизирующейся в начале транзакции (или когда сброс происходит). Точный механизм синхронизации меняется в зависимости от типа передачи; посмотрите спецификацию USB для подробных данных.
И узел и конечная точка начинают транзакцию с их обнуленных битов переключателя данных. В целом объект, получающий данные, переключает свой бит переключателя данных, когда это в состоянии принять данные, и это получает безошибочный пакет данных с корректной идентификацией. Объект, отправляющий данные, переключает свой бит переключателя данных, когда это получает положительное подтверждение от получателя. Таким образом биты переключателя данных остаются синхронизируемыми до, например, пакет с неправильной идентификацией получен. Когда это происходит, получатель игнорирует пакет и не постепенно увеличивает его бит переключателя данных. Когда биты переключателя данных выйдут из синхронизации (для этого или любой другой причины), Вы, вероятно, заметите, что альтернативные транзакции не проходят в Вашем приложении. Решение этого состоит в том, чтобы ресинхронизировать биты переключателя данных. Для получения информации о том, как сделать это, посмотрите Остановы Обработки, Остановы и Пересинхронизацию Переключателя Данных .
Игровые контроллеры
Современные игровые контроллеры и джойстик, игровой руль часто являются USB HID устройствами. В отличие от устройств, которые подключаются через игровой порт, USB HID устройства обычно не требуют драйверов для нормальной работы. Почти все игровые устройства будут работать с использованием встроенных драйверов, поскольку они разрабатываются с использованием USB HID спецификаций.
Функциональные характеристики
Примечательно то, что USB HID может быть использован как для описания работы самого устройства, так и для описания интерфейса устройства. Например, вполне допустимым будет использование USB устройства, имеющего два различных USB интерфейса одновременно (например, USB-телефон может использовать HID клавиатуру и USB аудио устройство для микрофона).
Интерфейс устройств также снабжен особым дескриптором, который определяет, является ли устройство загрузочным. Загрузочное устройство, строго соответствующее минимальным требованиям протокола, будет распознано и загружено BIOS. Каждый USB HID интерфейс связывается с хостом с использованием функции управления или функции прерывания.
Появилось немного свободного времени, и я решил написать небольшую «внеплановую» статью.
Итак, из предыдущей статьи, мы знаем, что для обмена данными используются некие виртуальные каналы – «конечные точки». Давайте рассмотрим, как происходит обмен.
Обмен данными по USB
Нужно помнить, что интерфейс USB предусматривает использование разветвлителей – хабов. Более того, допускается каскадное включение хабов. Следовательно, необходимо как-то идентифицировать конкретное USB устройство в «гирлянде» из хабов и USB устройств. Для этого каждому устройству присваивается адрес.
Здесь остановимся немного подробнее. Адрес кодируется 7 битами. Изначально (в момент подключения), устройство, грубо говоря, само себе назначает адрес 0. Этот адрес зарезервирован стандартом как раз для вновь подключаемых устройств. Далее, в процессе инициализации (об этом поговорим позже), хост присваивает устройству уникальный адрес отличный от 0, а адрес 0 «освобождается» для вновь подключаемых устройств.
И так, для того чтобы передать данные конкретному устройству, нужно знать адрес устройства и номер виртуального канала «внутри» устройства (адрес «конечной точки»).
Как мы уже выяснили, сразу после включения, устройство имеет особый, «нулевой» адрес. Каждое устройство, согласно стандарту, имеет «нулевую конечную точку» типа Control. Соответственно, сразу после подключения, хост может начинать обмениваться данными с новым устройством (адрес = 0, номер конечной точки = 0).
Рассмотрим, как происходит обмен данными.
Сам обмен осуществляется пакетами. Стандартом предусмотрено несколько типов пакетов. «Побайтно» мы пока разбирать пакеты не будем, но коснемся этого вопроса в практической части.
Дело в том, что часть работы по формированию и передаче пакетов (например, вопросы синхронизации, расчет контрольных сумм и т. д.) возьмет на себя USB периферия МК. Для тех, кто хочет сразу углубиться в биты и байты могу порекомендовать ознакомиться с разделом 8 официальной спецификации USB 2.0
Пока нам достаточно знать, что существуют «пакеты данных» и несколько типов «служебных пакетов».
USB и Plug and Play
Давайте рассмотрим, что с нашим устройством будет происходить дальше, после того как хост определил подключение нового устройства и готов начать обмен данными. Нам нужно ненадолго подняться на «высокий» уровень – уровень ОС.
Дело в том, что в стандарт USB поддерживает концепцию Plug and Play (подключи и играй). Данная концепция подразумевает, что пользователю достаточно «воткнуть» устройство в соответствующий порт ПК. Дальше ОС автоматически определит тип подключенного устройства, найдет подходящий для данного устройства драйвер, сконфигурирует устройство и т. д. (правда, это конечно в идеале :))
Для того чтобы вся эта красота работала, стандартом USB предусмотрены некие общие требования для всех устройств:
1. Каждое устройство содержит «собственное описание» (дескриптор устройства).
2. Есть некий, общий для всех USB устройств, механизм который позволяет ОС прочитать дескриптор устройства для того, чтобы идентифицировать устройство, узнать его характеристики.
3. Есть некий, общий для всех USB устройств, механизм который позволяет ОС выполнить первичную конфигурацию устройства (например, присвоить устройству новый адрес, о чем мы говорили выше).
Данными вещами (чтение дескриптора устройства, идентификация устройства) занимается некая служба ОС, которая отвечает за базовую поддержку USB.
После того как устройство будет идентифицировано и проведена некая первичная инициализация, данная служба передаст управление устройством драйверу, который «закреплен» за данным типом устройств (или конкретно за этим устройством).
Что будет, если служба не сможет найти «подходящий» драйвер для данного устройства знают все :)
Теперь возвращаемся на наш «низкий» уровень.
Начало работы с устройством. Стандартные заросы.
На практике, для чтения дескриптора устройства и первичной инициализации используются та самая «нулевая конечная точка». Есть несколько предусмотренных стандартом запросов (Standard Device Requests), которые должны обрабатываться всеми USB устройствами. Пока приведу несколько примеров таких запросов:
GET_DESCRIPTOR – запрос на получения дескриптора устройства. Данный запрос содержит дополнительную информацию о том, какой именно дескриптор должно вернуть (в устройстве «хранится» несколько разных дескрипторов, но об этом позже).
GET_CONFIGURATION – запрос на получение текущей конфигурации устройства.
SET_ADDRESS – данный запрос используется для присвоения устройству «нормального» (отличного от 0) адреса. Сам адрес содержится в запросе.
Нужно понимать, что запрос — это не более чем стандартизированная структура данных, которая содержит код запроса (bRequest) и дополнительные данные. Ответы на каждый из запросов тоже, естественно, стандартизированы.
Кроме стандартных запросов, которые устройство «обязано» поддерживать, можно определить «свои» запросы, специфические для конкретного устройства (класса устройств).
Заодно, для того чтобы показать как выглядит тот самый дескриптор устройства приведу пример:
Пока это просто иллюстрация того, как выглядит дескриптор, вникать в значение полей не стоит, этим мы займемся в следующей статье.
На этом, предлагаю завязывать с голой теорией и постепенно переходить к практике. В следующей статье начнем потихоньку писать код.
USB 2.0 и изохронные передачи
По большей части эти улучшения реализованы на программном уровне узла и не требуют изменений в Вашем коде. Для изохронных передач, однако, необходимо знать о следующих различиях:
Более ранние версии спецификации делят время шины на кадры с 1 миллисекундой, каждый из которых может перенести многократные транзакции многократным местам назначения. (Транзакция содержит два или больше пакета: маркерный пакет и один или несколько пакетов данных, пакет квитирования или оба.) Спецификация USB 2.0 делит кадр с 1 миллисекундой на восемь, микрокадры с 125 микросекундами, каждый из которых может перенести многократные транзакции многократным местам назначения.
Максимальная сумма данных, позволенных в транзакции, увеличена до 3 КБ.
Любые изохронные конечные точки в интерфейсе устройства по умолчанию должны иметь максимальный размер пакета нуля. (Это означает, что настройка по умолчанию для интерфейса, содержащего изохронные каналы, является альтернативным нулем установки, и максимальный размер пакета для изохронных конечных точек того интерфейса должен быть нулем.) Это гарантирует, что узел может сконфигурировать устройство независимо от того, насколько занятый шина.
Для сводки того, как эти различия влияют на OS X USB API, посмотрите Изменения в Изохронных Функциях для Поддержки USB 2.0 .
Типы USB-устройства и скорости шины
Спецификация USB поддерживает широкий выбор устройств, колеблющихся от устройств малого быстродействия, таких как клавиатуры, мыши и джойстики к устройствам более высокой скорости, таким как сканеры и цифровые фотоаппараты. Спецификация перечисляет много классов устройства, что каждый определяет ряд ожидаемых способов поведения устройства. Таблица 1-1 перечисляет некоторые примеры USB-устройств, категоризированных классом.
USB-устройства в классе
Класс устройства интерфейса чип-карты
Устройство, в котором вся специфичная для класса информация встраивается в ее интерфейсы
Клавиатуры, мыши, джойстики, таща планшеты
Концентраторы обеспечивают дополнительные точки подключения для USB-устройств
Класс массового хранения
Устройство, не вписывающееся ни в какой другой предопределенный класс или тот, не использующий стандартные протоколы для существующего класса
Цифровые видеокамеры, веб-камеры, цифровые цифровые видеокамеры для покадровой съемки та потоковая передача видео поддержки
Версия 1.1 спецификации USB поддерживает две скорости шины:
Низкая скорость (1,5 Мбит/с)
Полная скорость (12 Мбит/с)
Версия 2.0 спецификации добавляет другую скорость шины до этого списка:
Высокая скорость (480 Мбит/с)
Спецификация USB 2.0 полностью совместима с USB-устройствами низкоскоростной и полной скорости и даже поддерживает использование кабелей и коннекторов, сделанных встретить более ранние версии спецификации. Apple обеспечивает порты USB 2.0 на всех новых компьютерах Macintosh и полностью поддерживает новую спецификацию с контроллерами Усовершенствованного интерфейса хост-контроллера (EHCI) и встроенными, низкоуровневыми драйверами USB.
По большей части Вы не должны изменять существующие приложения для поддержки более быстрой скорости передачи данных, потому что увеличение скорости и другие улучшения реализованы на таком низком уровне. Исключения к этому являются некоторыми различиями в изохронных передачах. Для получения информации о том, как спецификация USB 2.0 влияет на изохронные передачи, посмотрите USB 2.0 и Изохронные Передачи .
Устройства класса составного объекта USB
Спецификация USB определяет составное устройство класса как устройство чьи поля дескриптора устройства для класса устройства ( bDeviceClass ) и подкласс устройства ( bDeviceSubClass ) у обоих есть значение 0 . Составное устройство класса появляется к системе как USB-устройство с помощью единственного адреса шины, который может представить многократные интерфейсы, каждый из которых представляет отдельную функцию. Хорошим примером составного устройства класса является многофункциональное устройство, такое как устройство, выполняющее печать, сканирование и отправление факсом. В таком устройстве каждая функция представлена отдельным интерфейсом. В OS X Набор I/O загружается AppleUSBComposite драйвер устройства для составных устройств класса, уже не имеющих специфичных для поставщика драйверов устройств для управления ими. AppleUSBComposite драйвер конфигурирует устройство и заставляет драйверы быть загруженными для каждого интерфейса USB.
Несмотря на то, что большинство многофункциональных USB-устройств является составными устройствами класса, не, все составные устройства класса являются многофункциональными устройствами. Производитель однофункционального USB-устройства имеет право классифицировать устройство как составное устройство класса, пока устройство соответствует спецификациям USB. Для получения дополнительной информации о том, как OS X представляет USB-устройства и интерфейсы, посмотрите USB-устройства на OS X .
Архитектура USB-устройства и терминология
Архитектура универсального USB-устройства является многослойной. Устройство состоит из одной или более конфигураций, каждая из которых описывает возможную установку устройства, может быть запрограммирован в. Такие настройки могут включать характеристики электропитания конфигурации (например, максимальная мощность, использованная конфигурацией и является ли это автономным или не), и поддерживает ли конфигурация удаленное пробуждение.
Каждая конфигурация содержит один или несколько интерфейсов, которые доступны после того, как установлена конфигурация. Интерфейс обеспечивает определения функций, доступных в устройстве, и может даже содержать альтернативные настройки в единственном интерфейсе. Например, интерфейс для аудиоустройства может иметь различные настройки, которые можно выбрать для различной пропускной способности.
Каждый интерфейс содержит нуль или больше конечных точек. Конечная точка является уникально идентифицируемой частью USB-устройства, которое является источником или приемником информации в коммуникационном потоке между узлом и устройством. Каждая конечная точка имеет характеристики, описывающие коммуникацию, которую она поддерживает, такие как тип передачи (управление, изохронное, прерывание или объем, описанный в Типах Передачи USB ), максимальный размер пакета и направление передачи (ввод или вывод).
Связь с USB-устройством выполняется через канал, логическую ассоциацию между конечной точкой и программным обеспечением, работающим на узле. Конечная точка и канал часто используются синонимично несмотря на то, что конечная точка является компонентом USB-устройства, и канал является логической абстракцией коммуникационного канала между конечной точкой и узлом.
USB-устройства на OS X
То, когда USB-устройство включается, семья OS X USB абстрагирует содержание дескриптора устройства в объект куска Набора I/O, вызвало IOUSBDevice . Этот объект куска присоединен IOService плоскость Реестра I/O как дочерний элемент драйвера для контроллера USB. IOUSBDevice объект куска тогда регистрируется для соответствия Набору I/O.
Если устройство является составным устройством класса без специфичного для поставщика драйвера для соответствия против него, AppleUSBComposite драйвер соответствует против него и запускается как его провайдер. AppleUSBComposite драйвер тогда конфигурирует устройство путем установки конфигурации в списке устройства дескрипторов конфигурации с использованием максимальной мощности, которое может быть удовлетворено портом, к которому присоединяется устройство. Это позволяет устройству с низкой мощностью и мощной конфигурацией быть сконфигурированным по-другому в зависимости от того, присоединено ли это к приводимому в действие шиной концентратору или автономному концентратору. Кроме того, если IOUSBDevice объект куска имеет свойство «Preferred Configuration», AppleUSBComposite драйвер будет всегда использовать то значение, когда это попытается сконфигурировать устройство.
Конфигурация устройства заставляет семью USB абстрагировать каждый интерфейсный дескриптор в выбранной конфигурации в IOUSBInterface объект куска. Эти объекты куска присоединены к Реестру I/O как к дочерним элементам оригинала IOUSBDevice объект куска и регистрируется для соответствия Набору I/O.
Важный: Поскольку составное устройство класса сконфигурировано AppleUSBComposite драйвер, устанавливая конфигурацию снова из Вашего приложения приведет к уничтожению IOUSBInterface кусок возражает и создание новых. В целом единственная причина установить конфигурацию составного устройства класса это является соответствующим AppleUSBComposite драйвер должен выбрать конфигурацию кроме первой.
Для несоставных устройств класса или составных устройств класса со специфичными для поставщика драйверами, соответствующими против них, нет никакой гарантии, что любая конфигурация будет установлена, и Вам, вероятно, придется выполнить эту задачу в Вашем приложении.
Важно помнить различие между USB-устройством (представленный в Реестре I/O IOUSBDevice объект куска) и его интерфейсы (каждый представленный IOUSBInterface объект куска). Многофункциональное USB-устройство, например, представлено в Реестре I/O одним IOUSBDevice возразите и один IOUSBInterface объект для каждого интерфейса.
Различие между интерфейсом и устройством важно, потому что это определяет, какой объект Ваше приложение должно найти в Реестре I/O и с каким типом устройства соединяют интерфейсом для получения. Например, если Ваше приложение должно связаться с определенным интерфейсом в многофункциональном USB-устройстве, оно должно найти, что интерфейс и добирается IOUSBInterfaceInterface связываться с ним. Приложение, которое должно связаться с USB-устройством в целом, с другой стороны, должно было бы найти устройство в Реестре I/O и добраться IOUSBDeviceInterface связываться с ним. Для получения дополнительной информации о нахождении устройств и интерфейсов в Реестре I/O, посмотрите USB-устройства Открытия и Интерфейсы ; для получения дополнительной информации о том, как заставить надлежащий интерфейс устройства связываться с устройством или взаимодействовать через интерфейс, видеть Используя Интерфейсы USB-устройства .
Другие устройства
Помимо детальных спецификаций классических устройств ввода (типа клавиатур и мышек) стандарт HID определяет особый класс устройств без детальных спецификаций. Этот класс именуется USB HID Consumer Control и представляет по сути нерегламентированный канал связи с устройством. При этом устройство пользуется теми же стандартными для операционной системы драйверами что и мышка с клавиатурой. Таким образом можно создать USB устройство которое не требует создания и инсталляции специальных драйверов в большинстве распространенных компьютерных операционных систем.
Этим стали массово пользоваться, и появилось огромное количество устройств, которые, по сути, интерфейсами взаимодействия с человеком не являются. Например, телефонное устройство, термометр [3] , устройство управления аудио и медицинское оборудование. Даже ИБП (источники бесперебойного питания) определяют себя, как принадлежащие классу USB HID, несмотря на то, что они часто не имеют человеческого интерфейса вообще. Любое устройство может принадлежать к USB HID классу, если оно удовлетворяет логическим спецификациям HID Consumer Control.
Клавиатуры
Клавиатуры — одни из наиболее популярных USB HID устройств. USB HID клавиатуры, как правило, имеют входной поток данных, который передаёт нажатия клавиш в компьютер и выходной поток, который передаёт текущий статус клавиатурных индикаторов от компьютера к клавиатуре. Стандарт PC 97 определяет, что BIOS компьютера должен определять USB HID клавиатуры и работать с ними. Стандарт разработан для того, чтобы эти клавиатуры возможно было использовать во время загрузки компьютера.
Компьютерная мышь — столь же популярное USB HID устройство, как и клавиатура. USB-мыши различаются по функционалу от простых однокнопочных до довольно сложных многокнопочных устройств. Большинство современных операционных систем поставляется с драйверами для стандартных HID мышей (наиболее распространённые современные мыши имеют две кнопки и колёсико, которое дублирует третью кнопку); мыши с более широким функционалом требуют драйверов от производителей.
Драйверы
Одно из преимуществ хорошо определенной спецификации, такой, как USB HID — это обилие драйверов устройств, доступных в большинстве современных операционных систем. USB HID класс и его базовые функции описаны в USB-IF документации, без какой-либо привязки к конкретному программному обеспечению. Из-за таких общих описаний разработчикам операционных систем легко включить функциональные драйверы для таких устройств как клавиатура, мышь и другие устройства взаимодействия с пользователем. Включение основных драйверов способствует более быстрому распространению этих устройств и упрощению установки конечными пользователями.
Компонентные дескрипторы USB-устройства
Каждый уровень USB-устройства предоставляет информацию о своих атрибутах и требованиях к ресурсам в ее дескрипторе, структура данных, доступная через функции интерфейса устройства. Путем исследования дескрипторов на каждом уровне можно определить точно, какую конечную точку необходимо передать успешно с определенным устройством.
В верхнем слое дескриптор устройства, которому связали поля с информацией, такие как класс и подкласс устройства, поставщик и номера продуктов и число конфигураций. Каждая конфигурация поочередно имеет дескриптор конфигурации, содержащий поля, описывающие число интерфейсов, которые это поддерживает и характеристики электропитания устройства, когда это находится в той конфигурации, вместе с другой информацией. Каждый интерфейс, поддерживаемый конфигурацией, имеет свой собственный дескриптор с полями для получения информации, такими как интерфейсный класс, подкласс, и протокол и число конечных точек в том интерфейсе. В нижнем слое дескрипторы конечной точки, указывающие атрибуты, такие как размер шрифта передачи и максимальный размер пакета.
Устройства
Класс USB HID описывает устройства, которые используются практически в каждом современном компьютере. В нём существует множество предопределённых функций. Они позволяют производителям аппаратного обеспечения разрабатывать продукты, соответствующие спецификации USB HID, и ожидать, что они будут работать с любым программным обеспечением, которое так же поддерживает эти спецификации.
Точно такой же HID-протокол используется неизменённым в Bluetooth, в профиле взаимодействия с пользователем. [2] При чтении спецификации HID-профиля Bluetooth читателей просто направляют к документации USB HID. По этой причине эти устройства можно так же отнести к классу USB HID.
Нахождение USB-устройств и интерфейсов
Ключи, определенные в спецификации, перечислены в таблицах ниже. Каждый ключ состоит из определенной комбинации элементов в устройстве или интерфейсном дескрипторе. В таблицах ниже, элементы в ключе разделяются ‘+’ символ для подчеркивания требования, чтобы весь элементы ключа появились вместе в соответствии словаря. Обе таблицы показывают ключи в порядке специфики: первый ключ в каждой таблице определяет самый определенный поиск, и последний ключ определяет самый широкий поиск.
Прежде чем Вы создадите соответствующий словарь, быть уверенными, что Вы знаете, должно ли Ваше приложение связаться с устройством или определенным интерфейсом в устройстве. Особенно важно знать об этом различии при работе с многофункциональными устройствами. Многофункциональное устройство часто является составным устройством класса, определяющим отдельный интерфейс для каждой функции. Если, например, Ваше приложение должно связаться с функцией сканирования устройства, делающего сканирование, отправление факсом и печать, необходимо создать словарь для соответствия в только интерфейсе сканирования (объект IOUSBInterface), не устройство в целом (объект IOUSBDevice). В этой ситуации Вы использовали бы ключи, определенные для интерфейса, соответствующего (показанные в Таблице 1-3 ), не ключи для соответствия устройства.
Таблица 1-2 перечисляет ключи, которые можно использовать для нахождения устройств (не интерфейсы). Каждый основной элемент является данными, содержавшимися в дескрипторе устройства для USB-устройства.
USB HID (human interface device) class — класс устройств USB для взаимодействия с человеком. Этот класс включает в себя такие устройства как клавиатура, мышь, игровой контроллер. Класс USB HID определен в нескольких документах, предоставляемых USB Implementers Forum, в частности, Рабочей группой по работе с устройствами.
Основной документ с дескрипторами класса: Device Class Definition for HID 1.11. В отдельных документах публикуются т.н. usage tables — списки кодов функций различных устройств ввода-вывода. [1]
Остановы и остановы
Несмотря на то, что останов и останов отличаются, они тесно связаны в своем эффекте на передачу данных. Останов является функцией конечной точки, и он может быть установлен или узлом или самим устройством в ответ на ошибку. Останов является типом пакета квитирования, который возвращает конечная точка, когда это неспособно передать или получить данные или когда его функция останова установлена (узел никогда не отправляет пакет останова). Когда конечная точка отправляет пакет останова, узел может остановить конечную точку.
В зависимости от точных обстоятельств и на том, насколько совместимый устройство, функция останова должна быть очищена в узле, конечной точке или обоих, прежде чем сможет возобновиться передача данных. То, когда останов очищен, переключатель данных укусил, используемый для синхронизации передачи данных, также сбрасывается (см. Синхронизацию Данных в Неизохронных Передачах для получения дополнительной информации о переключателе данных). Для получения информации о том, как обработать эти условия в Вашем приложении, посмотрите Остановы Обработки, Остановы и Пересинхронизацию Переключателя Данных .
Типы передачи USB
Спецификация USB определяет четыре типа передачи канала:
Управление — намеревалось поддерживать конфигурацию, команду и коммуникацию состояния между программным обеспечением узла и устройством. Передачи управления поддерживают обнаружение ошибок и повторную попытку.
Прерывание — раньше поддерживало маленький, ограниченная задержка передает или от устройства, такого как координаты от манипулятора, или состояние изменяется от модема. Передачи прерывания поддерживают обнаружение ошибок и повторную попытку.
Изохронный — используемый для периодической, постоянной связи между узлом и устройством, обычно включая информацию, важную для времени, такую как аудиоданные или потоки видеоданных. Изохронные передачи не поддерживают обнаружение ошибок или повторную попытку.
Объем — предназначенный для апериодической связи большого пакета с расслабленными ограничениями синхронизации такой как между программным обеспечением узла и принтером или сканером. Объемные передачи поддерживают обнаружение ошибок и повторную попытку.
Каналам также связали направление передачи с ними. Канал управления может поддерживать двунаправленную связь, но все другие каналы строго однонаправлены. Поэтому двухсторонняя связь требует двух каналов, один для ввода и один для вывода.
Каждое USB-устройство требуется, чтобы реализовывать канал управления по умолчанию, обеспечивающий доступ к конфигурации устройства, состоянию и управляющей информации. Этот канал, реализованный в IOUSBDevice объект куска (описанный в USB-устройствах на OS X ), используется когда драйвер такой как AppleUSBComposite когда специфичная для устройства управляющая информация и информация о статусе необходимы, драйвер конфигурирует устройство или. Например, Ваше приложение использовало бы канал управления по умолчанию, если это должно установить или выбрать конфигурацию для устройства. Канал управления по умолчанию подключен к конечной точке по умолчанию (конечная точка 0). Обратите внимание на то, что конечная точка 0 не обеспечивает дескриптор конечной точки, и это никогда не считается в общем количестве конечных точек в интерфейсе.
Интерфейсы, связанные с конфигурацией, могут содержать любую комбинацию трех остающихся типов канала (прерывание, изохронное, и объемное), реализованный в IOUSBInterface объекты куска (описанный в USB-устройствах на OS X ). Ваше приложение может запросить интерфейсные дескрипторы устройства для выбора канала большинство подходящее для его потребностей.
Читайте также: