Обслуживание периферии в коде модулей ядра: Часть 54. USB-устройства

Comments

В этой статье мы рассмотрим ещё один широкий класс устройств: сменные USB- устройства.

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

В стандарте USB описывается протокол "ведущий-ведомый" (master-slave), где ведущим является USB-хост, а ведомым— периферийное устройство. Контроллер хоста, в свою очередь, является одним из устройств на PCI-шине, как это обсуждалось ранее в предыдущих статьях:

$ lspci | grep USB 
00:1d.0 USB Controller: Intel Corporation N10/ICH 7 Family USB UHCI 
Controller #1 (rev 01) 
00:1d.1 USB Controller: Intel Corporation N10/ICH 7 Family USB UHCI 
Controller #2 (rev 01) 
...
00:1d.7 USB Controller: Intel Corporation N10/ICH 7 Family USB2 EHCI 
Controller (rev 01)

Термин USB охватывает четыре различные версии стандарта, которые, в основном различаются, скоростью обмена данными:

  • оригинальный стандарт 1.0 (низко-скоростной) допускает скорость обмена до 1.5MБ/с;
  • стандарт 1.1 (полно-скоростной) допускает скорость обмена до 12MБ/с;
  • стандарт 2.0 (высоко-скоростной) поддерживает скорость до 480MБ/с.

В данный момент текущей является версия 2.0, но уже появляются устройства, работающие по стандарту 3.0, который допускает ещё более высокую скорость обмена данными. Более скоростные стандарты обладают обратной совместимостью и поддерживают устройства предыдущих стандартов. Конструктивно обмен во всех версиях протокола USB организован по дифференциальной последовательной линии (контакты D+ и D-). Стандарт оговаривает 4-х контактные оконечные разъёмы, которые, кроме дифференциальной линии, содержат 2 линии питания оконечного устройства (стандарт USB OTG для мобильных устройств предусматривает наличие 5-го контакта для идентификации по признаку хост-устройство.)

В качестве хоста в системе могут присутствовать контроллеры разных стандартов (не совместимых на нижнем уровне интерфейса работы с хостом):

  • UHCI (Universal Host Controller Interface): спецификация, инициализированная компание Intel;
  • OHCI (Open Host Controller Interface): спецификация, созданная компаниями Compaq и Microsoft;
  • EHCI (Enhanced Host Controller Interface): спецификация для поддержки стандарта USB 2.0;
  • USB OTG (On The Go): спецификация, популярная во встраиваемых и мобильных устройствах, в частности, для поддержки dual-role (DRD) устройств, которые в зависимости от ситуации могут выступать как хост или как устройство.

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

$ cat /boot/config-`uname -r` | grep _USB_
...
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y 
CONFIG_USB_EHCI_HCD=y 
CONFIG_USB_OHCI_HCD=y 
CONFIG_USB_UHCI_HCD=y 
CONFIG_USB_WHCI_HCD=m 
...

Схема идентификации устройств c помощью пары значений VID:PID, уже знакомая нам по работе с PCI-устройствами, используется и для USB-устройств. В листинге ниже эти значения указываются после параметра ID.

$ lsusb 
Bus 001 Device 002: ID 0424:2503 Standard Microsystems Corp. USB 2.0 Hub 
Bus 001 Device 003: ID 1a40:0101 TERMINUS TECHNOLOGY INC. USB-2.0 4-Port HUB 
Bus 001 Device 005: ID 046d:080f Logitech, Inc. Webcam C120 
Bus 004 Device 002: ID 046d:c517 Logitech, Inc. LX710 Cordless Desktop Laser 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 
...
Bus 001 Device 006: ID 03f0:171d Hewlett-Packard Wireless (Bluetooth + WLAN) 
Interface [Integrated Module] 
Bus 001 Device 009: ID 16d5:6502 AnyDATA Corporation CDMA/UMTS/GPRS modem

К одному USB-контроллеру (разъёму) могут быть последовательно подключены до 127 устройств. Но непосредственно подключать одно устройство к другому нельзя, поскольку питание таких устройств осуществляется по той же шине. Поэтому для подключения дополнительных устройств используются специальные хабы, обеспечивающие снабжение устройств энергией. В результате USB-устройства образуют дерево, каждая нетерминальная вершина которого является хабом. Адрес каждого USB-устройства (т.е. параметры его размещения на шине) определяется в формате: <шина>:<устройство> (2 первые цифры в каждой строке). Устройство с номером 1 на каждой шине (из числа 127-ми возможных) — это корневой USB-разветвитель (хаб) для этой шины. Адресная информация может существенно меняться в зависимости от того, в какой разъём USB включается устройство, тогда как идентификация VID:PID остаётся закреплённой за устройством.

Список идентификаторов USB (VID:PID) централизовано поддерживается в сети в файле с именем usb.ids, а в некоторых дистрибутивах он может присутствовать и в самой системе. Но лучше воспользоваться самой свежей копией этого файла (образец такого файла по состоянию на 20 сентября 2012г. приведён в разделе "Материалы для скачивания"). Как видно, идентификация USB-устройств в основных чертах совпадает с идентификацией PCI-устройств PCI, но существуют и крайне серьёзные отличия.

$ cat usb.ids | wc -l 
17490

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

$ modprobe -c | grep -i 16d5 | grep -i 6502 
alias usb:v16D5p6502d*dc*dsc*dp*ic*isc*ip* option

Эта команда извлекает необходимую информацию из файла modules.alias:

$ cat /lib/modules/`uname -r`/modules.alias | grep -i 16d5 | grep -i 6502 
alias usb:v16D5p6502d*dc*dsc*dp*ic*isc*ip* option

В качестве тестового устройства в примерах, представленных ниже, будет использоваться EUDO-модем ADU-510A — один из представителей класса мобильных модемов. Как видно, это устройство поддерживается модулем option, о котором можно запросить дополнительную информацию:

$ modinfo option
filename: /lib/modules/2.6.42.12-1.fc15.i686.PAE/kernel/drivers/usb/serial/option.ko
license: GPL
version: v0.7.2
description: USB Driver for GSM modems
...
$ modprobe -c | grep -w option | wc -l
651

В подтверждение сказанного ранее, модуль option, как пример, поддерживает 651 модель разнообразных GSM/GPRS/CDMA модемов, и эта "нагрузка" на модуль растёт с появлением каждой новой версии ядра.

С помощью следующей команды можно просмотреть иерархическое дерево устройств по подключению (в листинге ниже приведена только часть выводимой информации):

$ lsusb -tv
/:  Bus 05.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
    |__ Port 1: Dev 2, If 0, Class=HID, Driver=usbhid, 1.5M
    |__ Port 1: Dev 2, If 1, Class=HID, Driver=usbhid, 1.5M
...
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/8p, 480M
...
    |__ Port 4: Dev 3, If 0, Class=hub, Driver=hub/4p, 480M
        |__ Port 4: Dev 9, If 0, Class=vend., Driver=option, 12M
        |__ Port 4: Dev 9, If 1, Class=vend., Driver=option, 12M

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

# lsusb -vv -d 16d5:6502 
Bus 001 Device 009: ID 16d5:6502 AnyDATA Corporation CDMA/UMTS/GPRS modem 
Device Descriptor: 
...
  idVendor           0x16d5 AnyDATA Corporation 
  idProduct          0x6502 CDMA/UMTS/GPRS modem 
...
# lsusb -vv -d 16d5:6502 | wc -l 
159

Ещё одним важным источником информации для разработчика при работе с USB-устройством является системный журнал, а именно сообщения, помещаемые туда подсистемами sysfs и udev при подключении устройства к USB-разъёму (о чём говорилось в 49-ой статье данного цикла).

$ dmesg
...
[22292.918081] usb 1-4: new high-speed USB device number 10 using ehci_hcd 
[22293.032635] usb 1-4: New USB device found, idVendor=1a40, idProduct=0101 
[22293.032645] usb 1-4: New USB device strings: Mfr=0, Product=1, SerialNumber=0 
[22293.032651] usb 1-4: Product: USB 2.0 Hub [MTT] 
[22293.033465] hub 1-4:1.0: USB hub found 
[22293.033609] hub 1-4:1.0: 4 ports detected 
[22293.296159] usb 1-4.4: new full-speed USB device number 11 using ehci_hcd 
[22293.372138] usb 1-4.4: New USB device found, idVendor=16d5, idProduct=6502 
[22293.372148] usb 1-4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0 
[22293.372154] usb 1-4.4: Product: AnyDATA CDMA Products 
[22293.372159] usb 1-4.4: Manufacturer: AnyDATA Corporation 
[22293.373474] option 1-4.4:1.0: GSM modem (1-port) converter detected 
[22293.373719] usb 1-4.4: GSM modem (1-port) converter now attached to ttyUSB0 
...

Ещё более подробную информацию можно получить из рассмотрения протокола асинхронных сообщений ядра при подключении устройства (выводимых командой udevadm, как это обсуждалось при рассмотрении udev).

Заключение

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


Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source
ArticleID=931168
ArticleTitle=Обслуживание периферии в коде модулей ядра: Часть 54. USB-устройства
publish-date=05232013