[DLA PRAKTYKÓW] USB w systemie Linux
Kontroler USB
Magistrala USB jest zarządzana przez kontroler. W komputerach PC jest on najczęściej urządzeniem PCI, w systemach embedded, stanowi jeden z elementów SoC-a (urządzenie platform).
Kontroler inicjuje wszystkie transfery. Urządzenie zawsze oczekuje na zapytanie z kontrolera. USB działa więc w trybie pollingu. Na przykład kontroler cyklicznie odpytuje endpointy interrupt urządzenia HID (mysz). Jeżeli urządzenie zgłosi dane oznaczające zmianę pozycji kursora – kontroler zgłosi odpowiednie przerwanie w systemie.
Endpoint może dostać skonfigurowany w trybie Out (do urządzenia) lub In (z urządzenia).
Transakcje mogą być inicjowane z poziomu przestrzeni użytkownika:
- przy użyciu biblioteki libusb :
API synchroniczne (http://libusb.org/static/api-1.0/group__syncio.html):libusb_control_transfer() libusb_interrupt_transfer() libusb_bulk_transfer()
API asynchroniczne (http://libusb.org/static/api-1.0/group__asyncio.html):
libusb_submit_transfer()
- z poziomu kodu w jądrze Linux:
usb_control_msg()
(https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/message.c?id=v4.0#n131)
usb_interrupt_msg()
(https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/message.c?id=v4.0#n183)
usb_bulk_msg()
(https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/message.c?id=v4.0#n223)
usb_submit_urb()
(https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/core/urb.c?id=v4.0#n325)
Ostatnia funkcja – działa asynchronicznie.
Klasy urządzeń
USB definiuje klasy dla typowych urządzeń. Klasa wyznacza zestaw endpointów i sposób ich konfiguracji. Dzięki klasom, jeden sterownik może obsługiwać wiele urządzeń różnych producentów. Typowym przykładem są pendrive-y i nagrwarki płyt.
http://www.usb.org/developers/defined_class
Obsługa USB w Linuksie
Jądro Linux implementuje wszystkie aspekty standardu USB. W konfiguracji źródeł jadra w wersji 4.0 znajdziemy sterowniki kontrolerów hosta, urządzeń (gadget). Także standardowych klas, oraz niektóre sterowniki dla konkretnych urządzeń (na przykład konwerterów USB-serial).
W przypadku drukarek i skanerów, komunikacja z urządzeniem zaimplementowana jest w całości w przestrzeni użytkownika (odpowiednio w programach: CUPS i sane).
Sterowniki i urządzenia zorganizowane są w magistralę zunifikowanego modelu urządzeń jądra Linux. Informacje i poszczególnych obiektach eksportowane są w postaci plików, katalogów i dowiązań symbolicznych w sysfs .
$ ls /sys/bus/usb/drivers ath3k cdc_acm cdc_subset hub uas usbfs usbserial usb-storage btusb cdc_ether ftdi_sio pl2303 usb usbhid usbserial_generic uvcvideo $ ls /sys/bus/usb/devices 1-0:1.0 1-1.2 1-1.3 1-1.3:1.2 4-0:1.0 4-2:1.1 6-1 usb1 usb4 1-1 1-1.2:1.0 1-1.3:1.0 2-0:1.0 4-2 5-0:1.0 6-1:1.0 usb2 usb5 1-1:1.0 1-1.2:1.1 1-1.3:1.1 3-0:1.0 4-2:1.0 6-0:1.0 6-1:1.1 usb3 usb6
Po podłączeniu urządzenia, informacje o jego wykryciu pojawiają się w buforze komunikatów jądra:
$ dmesg | tail usb 1-1.3: new full-speed USB device number 53 using xhci_hcd usb 1-1.3: New USB device found, idVendor=045e, idProduct=0745 usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 1-1.3: Product: Microsoft... Nano Transceiver v2.0
Identyfikator urządzenia zdradza informacje o jego położeniu na magistrali:
- 1 – pierwsza magistrala USB
- 1-1 – pierwsze złącze root hub-a. Jest to pierwszy element (hub) każdej magistrali. Wbudowany w kontroler zazwyczaj posiada jedno lub dwa złącza (wyprowadzenia).
- 1-1.3 – w omawianym przypadku, mysz USB podłączona jest do HUB-a w klawiaturze – konkretnie do trzeciego złącza.
W przypadku kiedy mysz zostanie podłączona przez kolejny HUB, urządzenie dostanie identyfikator:
1-1.3.4
Co wskazuje na czwarte złącze Hub-a. Obecność kolejnych rogałęźników sygnaliwowana jest przez dodanie segmentu <kropka>.<liczba>.
Komenda lsusb dostarcza ogólnych informacji o urządzeniach podłączonych do systemu (korzysta z wpisów w sysfs):
$ lsusb Bus 004 Device 003: ID 2232:1035 Silicon Motion Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 006 Device 059: ID 0cf3:3004 Atheros Communications, Inc. AR3012 Bluetooth 4.0 Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub # Mysz Bus 001 Device 062: ID 045e:0745 Microsoft Corp. Nano Transceiver v1.0 for Bluetooth # Drugi HUB Bus 001 Device 058: ID 05e3:0608 Genesys Logic, Inc. Hub Bus 001 Device 057: ID 05ac:0220 Apple, Inc. Aluminum Keyboard (ANSI) # Pierwszy HUB Bus 001 Device 056: ID 05ac:1006 Apple, Inc. Hub in Aluminum Keyboard Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub