¿Cómo vincular un dispositivo USB con un nombre estático?


43

Tengo un Arduino que a veces se une /dev/ttyUSB0y otras veces /dev/ttyUSB1, lo que hace que mi script falle.

No quiero enumerar todas las posibilidades de dónde podría estar mi dispositivo, sino que preferiría que esté vinculado a un lugar estático, por ejemplo /dev/arduino.

¿Cómo lo logro?


44
Simplemente escriba una regla udev simple que asignará el enlace simbólico / dev / arduino al diseño correcto por su VID y PID.
Eddy_Em


Respuestas:


41

Como se sugiere, puede agregar algunas reglas de udev. Edité el /etc/udev/rules.d/10-local.rulespara contener:

ACTION=="add", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="my_uart"

Puede verificar las variables de su dispositivo ejecutando

udevadm info -a -p  $(udevadm info -q path -n /dev/ttyUSB0)

Hay una guía más detallada que puede leer en http://www.reactivated.net/writing_udev_rules.html


Trabajado como un encanto. Una pregunta: ¿Cómo salir udevam? Y es importante tener en cuenta que my_uartcrea el enlace simbólico debajo /dev/my_uart. Escribí por /dev/arduinoprimera vez la primera vez y falló mientras arduinoes suficiente.
k0pernikus

udevadmdebería salir por sí solo cuando esté hecho.
Kotte

Luego, por alguna razón desconocida, congeló la sesión de terminal en mi Raspberry Pi mientras generaba el informe.
k0pernikus

35

La sintaxis de la regla anterior puede funcionar en algunas distribuciones, pero no funcionó en la mía (Raspbian). Como nunca encontré un solo documento que explica todos los entresijos, escribí el mío, que se encuentra aquí . Esto es a lo que se reduce.
1. descubre lo que hay en ttyUSB:

dmesg | grep ttyUSB  

2. enumere todos los atributos del dispositivo:

udevadm info --name=/dev/ttyUSBx --attribute-walk

(con su (s) número (s) de dispositivo en lugar de x, por supuesto). Elija un conjunto de identificadores únicos, por ejemplo, idVendor + idProduct. También puede necesitar SerialNumber si tiene más de un dispositivo con el mismo idVendor e idProduct. Los números de serie deben ser únicos para cada dispositivo.
3. Cree un archivo /etc/udev/rules.d/99-usb-serial.rulescon algo como esta línea:

SUBSYSTEM=="tty", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678", SYMLINK+="your_device_name" 

(suponiendo que no necesita un número de serie allí y, por supuesto, con los números de idVendor e idProduct que encontró en el paso 2.
4. Cargue la nueva regla:

sudo udevadm trigger

5. Verifique lo que sucedió:

ls -l /dev/your_device_name  

mostrará a qué número ttyUSB fue el enlace simbólico. Si es así /dev/ttyUSB1, verifique quién es el propietario y a qué grupo pertenece:

ls -l /dev/ttyUSB1   

Entonces solo por el gusto de hacerlo:

udevadm test -a -p  $(udevadm info -q path -n /dev/your_device_name)

Entonces, ¿hay alguna solución si el idVendory idProductson exactamente iguales? (dos sensores conectados en un modelo idéntico de USB a módulos UART)
Steven Lu

@StevenLu Sí, consulte el paso 2, haga udevadm info --name=/dev/ttyUSB1 --attribute-walkambos dispositivos y busque los números de serie, deben ser únicos para cada dispositivo. Si sus sensores no tienen número de serie, ¿puede especificar cuáles son?
RolfBly

eso es increíble, informaré cuando pruebe esto
Steven Lu

Mis dongles USB a UART de $ 2 tienen el número de serie 0001. No puedo decir que me sorprenda. Parece que tengo que identificar los sensores en función de su protocolo de salida.
Steven Lu

@StevenLu Mala suerte. Los convertidores FTDI USB-UART tienen un número de serie único, AFAIK. Unos cuantos dólares extra, pero menos tiempo para desarrollarse.
RolfBly

9

El problema de múltiples dispositivos USB idénticos

Tengo un Rasperry Pi con cuatro cámaras. Tomo pix con las fswebcamque se identifican las cámaras como /dev/video0.. video3. A veces, la cámara es video0, vide02, video4y video6pero puede olvidarse de eso por ahora.

Necesito una identificación persistente para identificar un número de cámara para que, por ejemplo, video0sea ​​siempre la misma cámara porque subtitulo las imágenes. Desafortunadamente, esto no sucede de manera confiable: en el arranque, las cámaras se enumeran como video0... video3pero no siempre de la misma manera.

Todas las cámaras tienen la misma identificación y número de serie.

La solución a este problema involucra las reglas de udev, pero también hay muchos anzuelos allí.

Si emite el comando

udevadm info –attribute-walk –path=/dev/video0

obtienes una regla de salida, pero los bits más destacados son

KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.

El bit KERNELS es un puerto concentrador USB. Con cuatro cámaras hay cuatro de estas: no cambian al reiniciar, pero las video{x}asociadas con un puerto pueden cambiar.

Por lo tanto, necesitamos una regla udev para vincular un número de video a un puerto concentrador USB, algo como:

KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0” 

Parece simple: acceda a la cámara con

fswebcam –d  $realpath /dev/camera0

Excepto que no funciona: si coloca esto en una regla udev y el sistema ha asignado video0 (en el arranque) a un puerto diferente, la regla udev se ignora. El enlace simbólico a /dev/camera0básicamente dice no such device. Un cuadrado.

Lo que queremos es vincular un enlace simbólico a una dirección de concentrador USB, no un video{x}número. Tomó un programa de Python.

El primer paso fue correr

fswebcam –d /dev/video${x}  tst.jpg

para xentre 1 y 8. La existencia de tst.jpgdespués de cada llamada identifica si hay una cámara en este número de video. A partir de esto, haga una lista de números de video activos. Mi experiencia ha sido que es 0,1,2,3o 0,2,4,6para las cámaras que he usado.

Otros, por supuesto, pueden construir esta lista utilizando un proceso diferente.

Luego, para cada número de video en la lista,

udevadm info –attribute-walk –path=/dev/videox > dd

y extraer el KERNELS= linede dd. De este proceso, termina con una lista de las direcciones de puerto USB para las cámaras. Ordene esta lista para que en el siguiente paso, siempre la procese en el mismo orden. Llame a esto la "lista de direcciones".

Ejecute la udevadm … > ddcosa nuevamente y haga una lista que se vea como

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.

Ahora recorra la lista de direcciones: para cada entrada, busque la entrada correspondiente en la lista de videos. Cree una nueva lista que se parezca a una colección de líneas como

KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”

La x (número de enlace simbólico) se reemplaza por el número de secuencia en la lista de direcciones.

Ahora tienes una regla de udev que funciona. Un enlace simbólico vinculado a una dirección de concentrador USB, sin importar el número de video asignado a ese puerto en el arranque.

Escribe la lista final en un archivo /etc/udev/rules.d/cam.rules. Ejecute udevadm triggerpara activarlo y el trabajo está hecho. /dev/camera2será la misma cámara (puerto USB) independientemente de su número de video.


Bienvenido a unix stackexchange. Por favor formatee su respuesta usando Markdown. Lo acabo de hacer por ti. También tenga en cuenta que queremos que las respuestas vayan al grano. Esto se lee más como una entrada de blog (que no es del todo malo), pero no es tan útil leer primero acerca de enfoques que no funcionaron. Puedes desechar esa parte.
k0pernikus

Lo siento. Soy nuevo aqui. He investigado este problema durante meses. Encontré a otros luchando con el mismo problema y no encontré una respuesta que funcionó para mí. Para que yo sepa, ¿dónde me aconsejarías que publique algo como esto? Me contuve y no incluí la fuente de Python :-)
Ian Boag

1

También pude encontrar un dispositivo único en /dev/serial/by-id. Todavía no he intentado reiniciar, pero los archivos en ese directorio eran solo enlaces al archivo de dispositivo apropiado ( ttyACM[0-9]).

Estoy ejecutando Arch Linux en Raspberry Pi, pero me topé con ellos simplemente haciendo un findnombre de archivo que contiene "Arduino". Mis programas de Python funcionan bien usando esos archivos como dispositivos para leer / escribir datos en / desde mis Arduinos (hasta ahora, dos en una sola Pi).


0

Solo para decir que lo anterior funcionó para mí y también montó automáticamente el dispositivo para mí después de haber colocado una entrada en / etc / fstab (y también llama a umount después de quitar el dispositivo)

es decir

/ etc / fstab

# See /etc/udev/rules.d/5-usb-disk.rules
/dev/backup     /vol/backup     ext4    defaults,errors=remount-ro 0       1

cat /etc/udev/rules.d/5-usb-stick.rules

#
# the next line creates a symlink to this disk drive called /dev/backup 
# i.e.
#   root:# ls -la /dev/backup 
#   lrwxrwxrwx 1 root root 3 Jul 22 19:33 /dev/backup -> sg0

# Backup usb stick - create /dev/backup
# ATTRS{model}=="Cruzer Blade    "
ACTION=="add", ATTRS{model}=="Cruzer Blade    ", SYMLINK+="backup"

# Clean up after removal  
ACTION=="remove", ATTRS{model}=="Cruzer Blade    ", RUN+="/bin/umount /vol/backup"

Entonces, después de insertar mi memoria USB obtengo:

root:# mount | grep sd
/dev/sda1 on /vol/backup type ext4 (rw,relatime,errors=remount-ro,data=ordered)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.