Enumeración coherente de dispositivos Linux

13

En nuestra caja de Linux tenemos USB -> dispositivo serie que siempre se identificó como /dev/ttyACM0. Así que escribí una solicitud y hasta ayer, todo funcionó bien. Pero de repente (sí, durante la presentación remota ...) el dispositivo dejó de funcionar. Después de una investigación rápida, descubrí que la conexión cambió a /dev/ttyACM1. Fue un poco inoportuno, pero ahora tengo un problema: ¿cómo identificar inequívocamente mi dispositivo? Al igual que, por ejemplo, la unidad de almacenamiento podría inicializarse usando UUID, aunque /dev/sd**ha cambiado. ¿Hay alguna forma de hacer eso para los dispositivos en serie?

Ahora uso una solución 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);
}

El enlace al dispositivo que utilizamos.

folibis
fuente

Respuestas:

19

Como estamos hablando de dispositivos USB y suponiendo que tenga udev, puede configurar algunas reglas de udev.

Supongo, y esto es solo una suposición descabellada, alguien o algo desconectó / retiró el dispositivo y lo enchufó nuevamente / agregó el dispositivo nuevamente, lo que aumenta el número.

Ahora, primero necesita la identificación del proveedor y del producto:

$ 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

A continuación, necesita el número de serie (en caso de que tenga varios):

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

Ahora, creemos una regla udev:

Las reglas UDEV generalmente están dispersas en muchos archivos /etc/udev/rules.d. Cree un nuevo archivo llamado 99-usb-serial.rulesy ponga la siguiente línea allí, tengo tres dispositivos, cada uno con un número de serie 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

Si no desea el número de serie, cualquier dispositivo del proveedor con el mismo chip obtendrá el mismo enlace simbólico, solo se puede conectar uno en un momento dado.

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

Tomado de aquí

thecarpy
fuente
3
Si tiene una distribución reciente de Linux, lo más probable es que ya cree automáticamente el dispositivo como /dev/serial/by-id/usb-XXXX_USB2.0-Serial-if00-port0. Esto podría ser suficiente para ti sin reglas personalizadas de udev.
Josef dice Reinstate Monica
1
Desafortunadamente, muchos dispositivos sin nombre tienen el número de serie "0123456789abcdef". Ahí es donde se pone interesante.
mosvy
@mosvy ¿los números de serie son inalterables?
OganM
@OganM pueden cambiarse ... si puede rootear los dispositivos.
mosvy