Spójne wyliczanie urządzeń Linux

13

W naszym Linux-ie mamy USB -> urządzenie szeregowe, które zawsze było identyfikowane jako /dev/ttyACM0. Napisałem więc aplikację i do wczoraj wszystko działało dobrze. Ale nagle (tak, podczas zdalnej prezentacji ...) urządzenie przestało działać. Po szybkich badaniach odkryłem, że połączenie zmieniło się na /dev/ttyACM1. To było trochę przedwczesne, ale teraz mam problem - jak jednoznacznie zidentyfikować moje urządzenie? Na przykład dysk pamięci masowej można zainicjować przy użyciu identyfikatora UUID, chociaż /dev/sd**zmienił się. Czy można to zrobić w przypadku urządzeń szeregowych?

Teraz używam głupiego obejścia:

for(int i = 0; i < 10; i ++)
{
    m_port = std::string("/dev/ttyACM") + (char)('0' + i);
    m_fd = open(m_port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
}

Link do urządzenia używamy.

folibis
źródło

Odpowiedzi:

19

Ponieważ mówimy o urządzeniach USB i zakładamy, że masz udev, możesz skonfigurować kilka reguł udev.

Wydaje mi się, że to tylko dzikie przypuszczenie, że ktoś lub coś odłączył / usunął urządzenie i podłączył je ponownie / dodał urządzenie ponownie, co powoduje wzrost liczby.

Teraz najpierw potrzebujesz identyfikatora dostawcy i produktu:

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 011: ID 0403:6001 FTDI FT232 USB-Serial (UART) IC

Następnie potrzebujesz numeru seryjnego (jeśli masz kilka):

# udevadm info -a -n /dev/ttyUSB1 | grep '{serial}' | head -n1
    ATTRS{serial}=="A6008isP"

Teraz stwórzmy regułę udev:

Reguły UDEV są zwykle rozproszone na wiele plików w /etc/udev/rules.d. Utwórz nowy plik o nazwie 99-usb-serial.rulesi wstaw tam następujący wiersz, mam trzy urządzenia, każde z innym numerem seryjnym:

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A6008isP", SYMLINK+="MySerialDevice"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A7004IXj", SYMLINK+="MyOtherSerialDevice"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="FTDIF46B", SYMLINK+="YetAnotherSerialDevice"

ls -l /dev/MySerialDevice
lrwxrwxrwx 1 root root 7 Nov 25 22:12 /dev/MySerialDevice -> ttyUSB1

Jeśli nie chcesz numeru seryjnego, każde urządzenie od tego samego układu otrzyma to samo dowiązanie symboliczne, tylko jedno może być podłączone w danym momencie.

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="MySerialDevice"

Zabrano stąd

karp
źródło
3
Jeśli masz najnowszą dystrybucję linux, najprawdopodobniej już automatycznie tworzy urządzenie jako /dev/serial/by-id/usb-XXXX_USB2.0-Serial-if00-port0. To może ci wystarczyć bez niestandardowych reguł udev.
Josef mówi Przywróć Monikę
1
Niestety wiele urządzeń bez nazwy ma numer seryjny „0123456789abcdef”. Właśnie tam robi się ciekawie.
mosvy
@mosvy czy numery seryjne są niewymienne
OganM
@OganM mogą zostać zmienione ... jeśli możesz zrootować urządzenia.
mosvy