LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

[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