Обзор USB-устройства

Эта глава обеспечивает сводку архитектуры USB-устройства и описывает, как USB-устройства представлены в OS X. Это также представляет несколько определенных инструкций для работы с USB-устройствами в приложении. Для получения дополнительной информации на спецификации USB, посмотрите http://www .usb.org.

Типы USB-устройства и скорости шины

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

Табличные 1-1  Примеры USB-устройств

Класс USB-устройства

USB-устройства в классе

Аудио класс

Динамики, микрофоны

Класс устройства интерфейса чип-карты

Смарт-карты, чип-карты

Коммуникационный класс

Спикерфон, модем

Составной класс

Устройство, в котором вся специфичная для класса информация встраивается в ее интерфейсы

Класс HID

Клавиатуры, мыши, джойстики, таща планшеты

Класс концентратора

Концентраторы обеспечивают дополнительные точки подключения для USB-устройств

Класс массового хранения

Жесткие диски, читатели флэш-памяти, диски Чтения-записи CD, цифровые фотоаппараты и высокопроизводительные медиапроигрыватели

Печать класса

Принтеры

Определенный поставщик

Устройство, не вписывающееся ни в какой другой предопределенный класс или тот, не использующий стандартные протоколы для существующего класса

Видео класс

Цифровые видеокамеры, веб-камеры, цифровые цифровые видеокамеры для покадровой съемки та потоковая передача видео поддержки

Версия 1.1 спецификации USB поддерживает две скорости шины:

Версия 2.0 спецификации добавляет другую скорость шины до этого списка:

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

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

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

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

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

Каждый интерфейс содержит нуль или больше конечных точек. Конечная точка является уникально идентифицируемой частью USB-устройства, которое является источником или приемником информации в коммуникационном потоке между узлом и устройством. Каждая конечная точка имеет характеристики, описывающие коммуникацию, которую она поддерживает, такие как тип передачи (управление, изохронное, прерывание или объем, описанный в Типах Передачи USB), максимальный размер пакета и направление передачи (ввод или вывод).

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

Компонентные дескрипторы USB-устройства

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

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

Спецификация USB определяет имя для каждого поля дескриптора, такой как bDeviceClass поле в дескрипторе устройства и bNumInterfaces поле в дескрипторе конфигурации и каждое поле связаны со значением. Для полного списка всех полей дескриптора посмотрите спецификацию USB в www.usb.org. Семья USB определяет структуры, представляющие дескрипторы, определенные спецификацией USB. Для определений этих структур посмотрите USB в ссылке платформы ядра.

Устройства класса составного объекта 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-устройство требуется, чтобы реализовывать канал управления по умолчанию, обеспечивающий доступ к конфигурации устройства, состоянию и управляющей информации. Этот канал, реализованный в IOUSBDevice объект куска (описанный в USB-устройствах на OS X), используется когда драйвер такой как AppleUSBComposite когда специфичная для устройства управляющая информация и информация о статусе необходимы, драйвер конфигурирует устройство или. Например, Ваше приложение использовало бы канал управления по умолчанию, если это должно установить или выбрать конфигурацию для устройства. Канал управления по умолчанию подключен к конечной точке по умолчанию (конечная точка 0). Обратите внимание на то, что конечная точка 0 не обеспечивает дескриптор конечной точки, и это никогда не считается в общем количестве конечных точек в интерфейсе.

Интерфейсы, связанные с конфигурацией, могут содержать любую комбинацию трех остающихся типов канала (прерывание, изохронное, и объемное), реализованный в IOUSBInterface объекты куска (описанный в USB-устройствах на OS X). Ваше приложение может запросить интерфейсные дескрипторы устройства для выбора канала большинство подходящее для его потребностей.

Остановы и остановы

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

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

Синхронизация данных в неизохронных передачах

Спецификация USB определяет простой протокол для обеспечения, синхронизация данных через многократные пакеты для неизохронных передач (вспомните, что изохронные передачи не поддерживают восстановление после ошибки или повторную попытку). Протокол реализован посредством бита переключателя данных и в узле и в конечной точке, синхронизирующейся в начале транзакции (или когда сброс происходит). Точный механизм синхронизации меняется в зависимости от типа передачи; посмотрите спецификацию USB для подробных данных.

И узел и конечная точка начинают транзакцию с их обнуленных битов переключателя данных. В целом объект, получающий данные, переключает свой бит переключателя данных, когда это в состоянии принять данные, и это получает безошибочный пакет данных с корректной идентификацией. Объект, отправляющий данные, переключает свой бит переключателя данных, когда это получает положительное подтверждение от получателя. Таким образом биты переключателя данных остаются синхронизируемыми до, например, пакет с неправильной идентификацией получен. Когда это происходит, получатель игнорирует пакет и не постепенно увеличивает его бит переключателя данных. Когда биты переключателя данных выйдут из синхронизации (для этого или любой другой причины), Вы, вероятно, заметите, что альтернативные транзакции не проходят в Вашем приложении. Решение этого состоит в том, чтобы ресинхронизировать биты переключателя данных. Для получения информации о том, как сделать это, посмотрите Остановы Обработки, Остановы и Пересинхронизацию Переключателя Данных.

USB 2.0 и изохронные передачи

Спецификация USB 2.0 поддерживает те же четыре типа передачи как более ранние версии спецификации. В дополнение к поддержке более высокой скорости передачи новая спецификация определяет улучшенный протокол для высокоскоростных передач и новых способов обработать транзакции для устройств низкоскоростной и полной скорости. Для получения дополнительной информации на протоколах и методах обработки транзакции, посмотрите спецификацию в http://www .usb.org.

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

  • Более ранние версии спецификации делят время шины на кадры с 1 миллисекундой, каждый из которых может перенести многократные транзакции многократным местам назначения. (Транзакция содержит два или больше пакета: маркерный пакет и один или несколько пакетов данных, пакет квитирования или оба.) Спецификация USB 2.0 делит кадр с 1 миллисекундой на восемь, микрокадры с 125 микросекундами, каждый из которых может перенести многократные транзакции многократным местам назначения.

  • Максимальная сумма данных, позволенных в транзакции, увеличена до 3 КБ.

  • Любые изохронные конечные точки в интерфейсе устройства по умолчанию должны иметь максимальный размер пакета нуля. (Это означает, что настройка по умолчанию для интерфейса, содержащего изохронные каналы, является альтернативным нулем установки, и максимальный размер пакета для изохронных конечных точек того интерфейса должен быть нулем.) Это гарантирует, что узел может сконфигурировать устройство независимо от того, насколько занятый шина.

Для сводки того, как эти различия влияют на OS X USB API, посмотрите Изменения в Изохронных Функциях для Поддержки USB 2.0.

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.

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

Важно помнить различие между USB-устройством (представленный в Реестре I/O IOUSBDevice объект куска) и его интерфейсы (каждый представленный IOUSBInterface объект куска). Многофункциональное USB-устройство, например, представлено в Реестре I/O одним IOUSBDevice возразите и один IOUSBInterface объект для каждого интерфейса.

Различие между интерфейсом и устройством важно, потому что это определяет, какой объект Ваше приложение должно найти в Реестре I/O и с каким типом устройства соединяют интерфейсом для получения. Например, если Ваше приложение должно связаться с определенным интерфейсом в многофункциональном USB-устройстве, оно должно найти, что интерфейс и добирается IOUSBInterfaceInterface связываться с ним. Приложение, которое должно связаться с USB-устройством в целом, с другой стороны, должно было бы найти устройство в Реестре I/O и добраться IOUSBDeviceInterface связываться с ним. Для получения дополнительной информации о нахождении устройств и интерфейсов в Реестре I/O, посмотрите USB-устройства Открытия и Интерфейсы; для получения дополнительной информации о том, как заставить надлежащий интерфейс устройства связываться с устройством или взаимодействовать через интерфейс, видеть Используя Интерфейсы USB-устройства.

Нахождение USB-устройств и интерфейсов

Для нахождения USB-устройства или интерфейса используйте ключи, определенные в Универсальной последовательной шине Общая Спецификация Класса, Версия 1.0 (доступный для скачивания от http://www .usb.org/developers/devclass_docs/usbccs10.pdf) для создания соответствующего словаря, определяющего определенный поиск. Если Вы незнакомы с понятием соответствия устройства, посмотрите раздел «Finding Devices in the I/O Registry» в Доступе к Аппаратным средствам Из Приложений.

Ключи, определенные в спецификации, перечислены в таблицах ниже. Каждый ключ состоит из определенной комбинации элементов в устройстве или интерфейсном дескрипторе. В таблицах ниже, элементы в ключе разделяются ‘+’ символ для подчеркивания требования, чтобы весь элементы ключа появились вместе в соответствии словаря. Обе таблицы показывают ключи в порядке специфики: первый ключ в каждой таблице определяет самый определенный поиск, и последний ключ определяет самый широкий поиск.

Прежде чем Вы создадите соответствующий словарь, быть уверенными, что Вы знаете, должно ли Ваше приложение связаться с устройством или определенным интерфейсом в устройстве. Особенно важно знать об этом различии при работе с многофункциональными устройствами. Многофункциональное устройство часто является составным устройством класса, определяющим отдельный интерфейс для каждой функции. Если, например, Ваше приложение должно связаться с функцией сканирования устройства, делающего сканирование, отправление факсом и печать, необходимо создать словарь для соответствия в только интерфейсе сканирования (объект IOUSBInterface), не устройство в целом (объект IOUSBDevice). В этой ситуации Вы использовали бы ключи, определенные для интерфейса, соответствующего (показанные в Таблице 1-3), не ключи для соответствия устройства.

Таблица 1-2 перечисляет ключи, которые можно использовать для нахождения устройств (не интерфейсы). Каждый основной элемент является данными, содержавшимися в дескрипторе устройства для USB-устройства.

Табличные 1-2  Ключи для нахождения USB-устройства

Ключ

Примечания

idVendor + idProduct + bcdDevice

bcdDevice содержит номер выпуска устройства

idVendor + idProduct

idVendor + bDeviceSubClass + bDeviceProtocol

Используйте этот ключ только если устройство bDeviceClass $FF

idVendor + bDeviceSubClass

Используйте этот ключ только если устройство bDeviceClass $FF

bDeviceClass + bDeviceSubClass + bDeviceProtocol

Используйте этот ключ только если устройство bDeviceClass не $FF

bDeviceClass + bDeviceSubClass

Используйте этот ключ только если устройство bDeviceClass не $FF

Таблица 1-3 перечисляет ключи, которые можно использовать для нахождения интерфейсов (не устройства). Каждый основной элемент является данными, содержавшимися в интерфейсном дескрипторе для USB-устройства.

Табличные 1-3  Ключи для нахождения интерфейса USB

Ключ

Примечания

idVendor + idProduct + bcdDevice + bConfigurationValue + bInterfaceNumber

idVendor + idProduct + bConfigurationValue + bInterfaceNumber

idVendor + bInterfaceSubClass + bInterfaceProtocol

Используйте этот ключ только если bInterfaceClass $FF

idVendor + bInterfaceSubClass

Используйте этот ключ только если bInterfaceSubClass $FF

bInterfaceClass + bInterfaceSubClass + bInterfaceProtocol

Используйте этот ключ только если bInterfaceSubClass не $FF

bInterfaceClass + bInterfaceSubClass

Используйте этот ключ только если bInterfaceSubClass не $FF

Для успешного поиска необходимо добавить элементы точно одного ключа к соответствию словаря. Если Ваше соответствие словаря будет содержать комбинацию элементов, не определенных каким-либо ключом, то поиск будет неуспешен. Например, даже если устройство с теми точными значениями в его дескрипторе устройства будет в настоящее время представлено, при создании соответствующего словаря, содержащего значения, представляющие поставщика устройства, продукт и протокол, поиск будет неуспешен IOUSBDevice кусок в Реестре I/O. Это вызвано тем, что нет никакого ключа в Таблице 1-2, объединяющейся idVendor, idProduct, и bDeviceProtocol элементы.

Коды ошибки семьи USB

Поскольку Вы разрабатываете приложение для доступа к USB-устройству или интерфейсу, Вы, вероятно, встретитесь с кодами ошибки, определенными для семьи OS X USB. При использовании XCode можно искать информацию об этих кодах ошибки в окне документации XCode.

Для нахождения документации кода ошибки выберите Documentation из Меню справки XCode. Выберите Full-Text Search из выпадающего меню, связанного с полем поиска (щелкните по значку лупы для раскрытия меню). Выберите Reference Library в области Search Groups слева от окна. Введите число кода ошибки в поле поиска, таком как 0xe0004057, и нажмите Return. Выберите самую соответствующую запись в результатах поиска вывести на экран документ в более низкой части окна. Используйте команду Find (нажмите Command-F) найти код ошибки в этом документе. Используя пример кода ошибки 0xe0004057, Вы будете видеть, что эта ошибка возвращается, когда не была найдена конечная точка.

Для справки с дешифровкой кодов ошибки Набора I/O в целом, посмотрите Технические Вопросы и ответы QA1075, “Поняв коды ошибки Набора I/O”.

Определение, который версия интерфейса использовать

Как описано в USB-устройствах на OS X, семья OS X USB обеспечивает IOUSBDeviceInterface возразите, что Вы используете для передачи с USB-устройством в целом и IOUSBInterfaceInterface возразите, что Вы используете для передачи с интерфейсом в USB-устройстве. Существует много различных версий семьи USB, однако, некоторые из которых обеспечивают новые версии этих интерфейсных объектов. (Один способ счесть версию семьи USB установленной в Вашем компьютере состоит в том, чтобы просмотреть информацию о предварительном просмотре Средства поиска для IOUSBFamily.kext расположенный в /System/Library/Extensions.) В этом разделе описывается удостовериться, что Вы используете корректный интерфейсный объект и как просмотреть документацию для интерфейсных объектов.

Первая версия семьи USB была представлена в OS X v10.0 и содержит первые версии интерфейсных объектов IOUSBDeviceInterface и IOUSBInterfaceInterface. Когда новые версии семьи USB представляют новые функции для интерфейсного объекта, новая версия интерфейсного объекта создается, который предоставляет доступ и к новым функциям и ко всем функциям, определяемым во всех предыдущих версиях того интерфейсного объекта. Например, IOUSBDeviceInterface197 объект обеспечивает две новых функции, которые можно использовать с версией 1.9.7 семьи USB (доступный в OS X v10.2.3 и позже), в дополнение ко всем функциям, доступным в предыдущих объектах интерфейса устройства IOUSBDeviceInterface187, IOUSBDeviceInterface182, и IOUSBDeviceInterface.

Поскольку Вы разрабатываете приложение, получающее доступ к USB-устройству или интерфейсу, необходимо использовать последнюю версию интерфейсного объекта, который доступен в самой ранней версии OS X, который Вы хотите поддерживать. Например, если Ваше приложение должно работать в OS X v10.0, необходимо использовать IOUSBDeviceInterface и IOUSBInterfaceInterface объекты. Однако, при разработке приложения для выполнения в OS X v10.4 и позже, Вы используете IOUSBDeviceInterface197 возразите для доступа к устройству в целом и IOUSBInterfaceInterface220 возразите для доступа к интерфейсу в нем. Это вызвано тем, что IOUSBDeviceInterface197 доступно в версии 10.2.3 OS X и позже и IOUSBInterfaceInterface220 доступно в OS X v10.4 и позже.

Задачи и протесты

Этот раздел представляет некоторые определенные задачи, которые Ваше приложение, возможно, должно было бы выполнить, вместе с некоторыми протестами, связанными с поддержкой USB 2.0, о которой необходимо знать.

Обработка остановов, остановов и пересинхронизации переключателя данных

Как описано в Остановах и Остановах, остановы и остановы тесно связаны в их эффекте на передачу данных. Для упрощения API семья USB использует терминологию останова канала на имена функций, обрабатывающих эти условия:

  • ClearPipeStall

  • ClearPipeStallBothEnds

ClearPipeStall функция воздействует исключительно на сторону хост-контроллера, очищая функцию останова и сбрасывая бит переключателя данных для обнуления. Если функция останова конечной точки и бит переключателя данных должны быть сброшены также, Ваше приложение должно сделать так явно, с помощью одного из ControlRequest функции для отправления надлежащего запроса устройства. См. документацию для USB.h заголовочный файл в Ссылке Платформы Набора I/O для получения дополнительной информации о запросах стандартного устройства.

В версии 10.2 OS X и позже, можно использовать ClearPipeStallBothEnds функция, который, как ее имя предполагает, очищает останов и сбрасывает бит переключателя данных с обеих сторон одновременно.

Используя низкую задержку изохронные функции

В OS X время между тем, когда изохронная транзакция завершается на Шине USB и когда Вы получаете свой обратный вызов, может простираться к десяткам миллисекунд. Это вызвано тем, что обратный вызов происходит на цикле работы семьи USB, работающем в более низком приоритете, чем некоторые другие потоки в системе. В большинстве случаев можно работать вокруг этой задержки путем организации очередей чтения и записать запросы так, чтобы следующая транзакция была запланирована и готова запуститься перед получением обратного вызова из текущей операции. Фактически, эта схема является хорошим способом достигнуть более высокой производительности, является ли низкая задержка требованием Вашего приложения.

В нескольких случаях, однако, ставя изохронные транзакции в очередь для поддержания занятости канала недостаточно для предотвращения проблемы задержки, которую мог бы заметить пользователь. Рассмотрите заявление, выполняющее обработку аудиоданных на некотором вводе USB (от музыкального инструмента, например) перед отсылкой обработанных данных динамикам USB. В этом сценарии пользователь слышит и сырые данные, необработанный вывод инструмента и обработанный вывод динамиков. Конечно, некоторая маленькая задержка между временем, инструмент создает необработанные звуковые волны и время динамик, испускает обработанные звуковые волны, неизбежно. Если эта задержка будет больше, чем приблизительно 8 миллисекунд, однако, то пользователь заметит.

В версии 10.2.3 OS X (версия 1.9.2 семьи USB) семья USB решает эту проблему путем использования в своих интересах предсказуемости изохронной передачи данных. По определению изохронный режим гарантирует поставку некоторого объема данных каждый кадр или микрокадр. В более ранних версиях OS X, однако, не было возможно узнать точный объем данных, переданный данным временем. Это означало, что приложение не могло начать обрабатывать данные, пока это не получило обратный вызов, связанный с транзакцией, говоря ему состояние переадресации и фактическую сумму переданных данных.

Версия 1.9.2 семьи USB представила LowLatencyReadIsochPipeAsync и LowLatencyWriteIsochPipeAsync функции. Эти функции обновляют информацию о списке кадра (включая состояние переадресации и число байтов, фактически переданных) в основное время прерывания. Используя эти функции, приложение может запросить, чтобы информация о списке кадра обновлялась так же часто как каждая миллисекунда. Это означает, что приложение может получить и начать обрабатывать число байтов, фактически переданных один раз миллисекунда, не ожидая всей транзакции для завершения.

Для поддержки низкой задержки изохронное чтение и функции записи семья USB также представила функции, чтобы создать и уничтожить буферы, содержащие информацию о списке кадра и данные. Несмотря на то, что можно принять решение создать единственный буфер данных и единственный список кадра буферные или многократные буферы каждого типа, необходимо использовать LowLatencyCreateBuffer функция для создания их. Точно так же необходимо использовать LowLatencyDestroyBuffer функция для уничтожения буферов после того, как Вы закончены с ними. Это ограничивает всю необходимую связь с объектами ядра семье USB.

Для справочной документации на низкой задержке изохронные функции посмотрите IOUSBLib.h документация в Ссылке Платформы Набора I/O.

Ошибки, о которых сообщает концентратор EHCI

Концентратор EHCI, поддерживающий высокоскоростные устройства (а также устройства низкоскоростной и полной скорости) обеспечивает сообщение об ошибке с более грубыми зернами, чем концентратор OHCI. Например, с концентратором OHCI, Вы могли бы получить “конечную точку, приведенную к таймауту” ошибка при отключении устройства, в то время как это активно. При выполнении того же действия с концентратором EHCI Вы могли бы получить “канал, остановленный” ошибка вместо этого.

Драйвер концентратора EHCI Apple не может получить более подробную ошибочную информацию от концентратора, таким образом, это чередуется между созданием отчетов “об устройстве, не отвечающем” и “каналом, остановленным” независимо от фактической ошибки, о которой сообщает устройство. Чтобы избежать проблем с Вашим кодом, быть уверенным, Ваше приложение не полагается на другой, более определенные ошибки принять важные решения.

Изменения в изохронных функциях для поддержки USB 2.0

Вспомните, что спецификация USB 2.0 делит кадр с 1 миллисекундой на восемь, микрокадры с 125 микросекундами. Семья USB обрабатывает это путем иного толкования некоторым параметрам функции (где это необходимо), и добавления нескольких новых функций. Этот раздел суммирует эти изменения; для справочной документации см. документацию для IOUSBLib.h в Ссылке Платформы Набора I/O.

Функции, которые Вы используете, чтобы читать из и записать в изохронные конечные точки, ReadIsochPipeAsync и WriteIsochPipeAsync. Обе функции включают следующие два параметра:

  • numFrames — Число кадров, для которых можно передать данные

  • frameList — Указатель на массив структур, описывающих кадры

Если необходимо обработать высокоскоростные изохронные передачи, можно думать об этих параметрах как относящийся для “передачи возможностей” вместо кадров. Другими словами, numFrames может относиться ко многим кадрам для устройств полной скорости или ко многим микрокадрам для высокоскоростных устройств. Точно так же frameList указывает список передач, Вы хотите произойти, являются ли они с точки зрения кадров или микрокадров.

Чтобы помочь Вам определить, функционирует ли устройство в полной скорости или высокоскоростном режиме, семья USB добавила GetFrameListTime функция, возвращающая число микросекунд в кадре. Путем исследования результата (kUSBFullSpeedMicrosecondsInFrame или kUSBHighSpeedMicrosecondsInFrame) можно сказать, в котором режиме работает устройство.

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

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

  1. Вызвать GetBandwidthAvailable (доступный в версии 10.2 OS X и позже) для определения, сколько пропускной способности в настоящее время доступно для выделения к изохронным конечным точкам.

  2. Вызвать GetEndpointProperties (доступный в версии 10.2 OS X и позже), чтобы исследовать альтернативные настройки интерфейса и найти тот, использующий ассигновать сумму в размере пропускной способности.

  3. Вызвать SetAlternateInterface (доступный в версии 10.0 OS X и позже), чтобы создать желаемый интерфейс и выделить объекты канала.

  4. Вызвать GetPipeProperties (доступный в версии 10.0 OS X и позже) на выбранной изохронной конечной точке. Это - очень важный шаг потому что SetAlternateInterface даже если будет недостаточно пропускной способности для конечных точек, успешно выполнится. Кроме того, другое устройство, возможно, требовало пропускной способности, которая была доступна в это время GetBandwidthAvailable функция возвратилась. Если это происходит, максимальный размер пакета для Вашей выбранной конечной точки (содержавшийся в maxPacketSize поле), теперь нуль, что означает, что пропускная способность больше не доступна.

Кроме того, в версии 10.2 OS X, семья USB добавила SetPipePolicy функция, позволяющая Вам оставлять пропускную способность, которая, возможно, была указана в альтернативной установке.

Доступ USB-устройства в основанном на Intel Macintosh

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

Прежде чем Вы создадите свое приложение как универсальный двоичный файл, удостоверьтесь что:

Шина USB является шиной с прямым порядком байтов. Структурированные данные появляются на шине в формате с прямым порядком байтов независимо от собственного формата порядка байтов компьютера, в котором работает приложение. При разработке приложения доступа к устройствам USB для выполнения в основанном на PowerPC Macintosh, Вы, вероятно, выполняете некоторый свопинг байта на данных, которые Вы считываете из Шины USB, потому что процессор PowerPC использует формат с обратным порядком байтов. Например, структура дескриптора конфигурации USB содержит двухбайтовое поле, содержащее длину дескриптора. Если Ваше приложение PowerPC читает эту структуру из Шины USB (вместо того, чтобы получить его от функции интерфейса USB-устройства), необходимо подкачать значение от формата Шины USB (прямой порядок байтов) к формату PowerPC (обратный порядок байтов).

Семья USB обеспечивает несколько макросов свопинга, которые подкачивают от USB для хостинга и от узла до USB (для получения дополнительной информации о них макросы, посмотрите USB.h). Платформа Ядра также обеспечивает подкачивающие байт макросы и функционирует, можно использовать в высокоуровневых приложениях (см. OSByteOrder.h заголовочный файл в libkern). При использовании их макросы в приложении Вы не должны испытывать никакие затруднения при разработке универсальной версии двоичных файлов приложения. Это вызвано тем, что они, которые макросы определяют во время компиляции, если подкачка необходима. Если, однако, Ваше приложение будет использовать трудно кодированные подкачки от прямого порядка байтов до обратного порядка байтов, то Ваше приложение не будет работать правильно в основанном на Intel Macintosh. Поскольку Вы разрабатываете универсальную версию двоичных файлов своего приложения, поэтому, убедиться использовать семью USB, загружающую макросы или макросы libkern/OSByteOrder.h для всего свопинга байта.

Несмотря на то, что Вы, возможно, должны выполнить свопинг байта на значениях Ваши чтения приложения от Шины USB, Вы не должны выполнять свопинг байта на значениях, Вы передаете в параметрах функциям в семье USB API. Необходимо передать значения аргументов в формате узла компьютера. Аналогично, любые значения, которые Вы получаете от функций семьи USB, будут в формате узла компьютера.