Enumeração consistente de dispositivos Linux

13

Na nossa caixa Linux, temos um dispositivo serial USB -> que sempre foi identificado como /dev/ttyACM0. Então, eu escrevi uma inscrição e até ontem tudo funcionou bem. Mas de repente (sim, durante a apresentação remota ...) o dispositivo parou de funcionar. Após uma pesquisa rápida, descobri que a conexão mudou para /dev/ttyACM1. Foi um pouco prematuro, mas agora tenho um problema - como identificar inequivocamente meu dispositivo? Por exemplo, a unidade de armazenamento pode ser inicializada usando UUID, embora a /dev/sd**alteração tenha sido alterada. Existe alguma maneira de fazer isso em dispositivos seriais?

Agora eu uso uma solução estúpida:

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);
}

O link para o dispositivo que usamos.

folibis
fonte

Respostas:

19

Como estamos falando de dispositivos USB e assumindo que você possui o udev, você pode configurar algumas regras do udev.

Eu acho, e isso é apenas um palpite, alguém ou algo desconectou / removeu o dispositivo e o conectou novamente / adicionou o dispositivo novamente, o que aumenta o número.

Agora, primeiro você precisa de IDs de fornecedor e produto:

$ 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

Em seguida, você precisa do número de série (caso tenha vários):

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

Agora, vamos criar uma regra do udev:

As regras UDEV geralmente são espalhadas em muitos arquivos no /etc/udev/rules.d. Crie um novo arquivo chamado 99-usb-serial.rulese coloque a seguinte linha, eu tenho três dispositivos, cada um com um número de série diferente:

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

Se você não quiser o número de série, qualquer dispositivo do fornecedor com o mesmo chip receberá o mesmo link simbólico, apenas um poderá ser conectado a qualquer momento.

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

Retirado daqui

thecarpy
fonte
3
Se você possui uma distribuição Linux recente, provavelmente já cria o dispositivo automaticamente como /dev/serial/by-id/usb-XXXX_USB2.0-Serial-if00-port0. Isso pode ser o suficiente para você, sem regras personalizadas do udev.
Josef diz Restabelecer Monica
1
Infelizmente, muitos dispositivos sem nome têm o número de série "0123456789abcdef". É aí que fica interessante.
mosvy
@mosvy os números de série são imutáveis?
OganM
@ OganM eles podem ser alterados ... se você conseguir fazer root nos dispositivos.
mosvy