web-dev-qa-db-fra.com

Comment lier un périphérique USB sous un nom statique?

J'ai un Arduino qui se lie parfois à /dev/ttyUSB0 et d'autres fois à /dev/ttyUSB1, faisant échouer mon script.

Je ne veux pas énumérer toutes les possibilités de l'emplacement de mon appareil, mais je préfère qu'il soit lié à un endroit statique, par exemple /dev/arduino.

Comment puis-je y parvenir?

46
k0pernikus

Comme suggéré, vous pouvez ajouter quelques règles udev. J'ai édité le /etc/udev/rules.d/10-local.rules contenir:

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

Vous pouvez vérifier les variables de votre appareil en exécutant

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

Il existe un guide plus approfondi sur lequel vous pouvez lire http://www.reactivated.net/writing_udev_rules.html

43
Kotte

La syntaxe des règles ci-dessus peut fonctionner sur certaines distributions, mais n'a pas fonctionné sur la mienne (Raspbian). Comme je n'ai jamais trouvé un seul document qui explique tous les tenants et aboutissants, j'ai écrit le mien, à trouver ici . Voilà à quoi cela se résume.
1. découvrez ce qui est sur ttyUSB:

dmesg | grep ttyUSB  

2. répertoriez tous les attributs de l'appareil:

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

(avec votre numéro d'appareil au lieu de x, bien sûr). Choisissez un ensemble d'identifiants uniques, par exemple idVendor + idProduct. Vous pouvez également avoir besoin de SerialNumber si vous avez plusieurs appareils avec les mêmes idVendor et idProduct. Les numéros de série doivent être uniques pour chaque appareil.
3. Créez un fichier /etc/udev/rules.d/99-usb-serial.rules avec quelque chose comme cette ligne:

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

(en supposant que vous n'avez pas besoin d'un numéro de série là-bas, et bien sûr avec les numéros pour idVendor et idProduct que vous avez trouvés à l'étape 2.
4. Chargez la nouvelle règle:

Sudo udevadm trigger

5. Vérifiez ce qui s'est passé:

ls -l /dev/your_device_name  

montrera à quel numéro ttyUSB le lien symbolique est allé. Si c'est /dev/ttyUSB1, puis vérifiez qui en est propriétaire et à quel groupe il appartient:

ls -l /dev/ttyUSB1   

Alors juste pour le plaisir:

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

Le problème de plusieurs périphériques USB identiques

J'ai un Rasperry Pi avec quatre caméras. Je prends pix avec fswebcam qui identifie les caméras comme /dev/video0 .. video3. Parfois, la caméra est video0, vide02, video4 et video6 mais on peut oublier ça pour l'instant.

J'ai besoin d'un ID persistant pour identifier un numéro de caméra afin que, par exemple video0 est toujours le même appareil photo car je sous-titre les photos. Malheureusement, cela ne se produit pas de manière fiable - au démarrage, les caméras sont énumérées comme video0..video3 mais pas toujours de la même manière.

Les caméras ont toutes le même identifiant et numéro de série.

La solution à ce problème implique des règles udev, mais il y a aussi beaucoup d'hameçons.

Si vous exécutez la commande

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

vous obtenez une chape de sortie, mais les bits saillants sont

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

Le bit KERNELS est un port de concentrateur USB. Avec quatre caméras, il y en a quatre - elles ne changent pas au redémarrage, mais le video{x} associé à un port peut changer.

Nous avons donc besoin d'une règle udev pour lier un numéro vidéo à un port de concentrateur USB - quelque chose comme:

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

Semble simple - accédez à la caméra avec

fswebcam –d  $realpath /dev/camera0

Sauf que cela ne fonctionne pas - si vous mettez cela dans une règle udev et que le système a alloué video0 (au démarrage) à un autre port, la règle udev est ignorée. Le lien symbolique vers /dev/camera0 dit essentiellement no such device. Carré un.

Ce que nous voulons, c'est lier un lien symbolique à une adresse de concentrateur USB, pas un video{x} nombre. Il a fallu un programme Python.

La première étape consistait à exécuter

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

pour x entre 1 et 8. L'existence de tst.jpg après chaque appel identifie s'il y a une caméra sur ce numéro de vidéo. À partir de cela, faites une liste des numéros de vidéo actifs. D'après mon expérience, c'est soit 0,1,2,3 ou 0,2,4,6 pour les caméras que j'ai utilisées.

D'autres peuvent bien sûr construire cette liste en utilisant un processus différent.

Ensuite, pour chaque numéro de vidéo dans la liste, exécutez

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

et extraire le KERNELS= line de dd. À partir de ce processus, vous vous retrouvez avec une liste des adresses de port USB pour les caméras. Triez cette liste afin qu'à l'étape suivante, vous la traitiez toujours dans le même ordre. Appelez cela la "liste d'adresses".

Exécutez le udevadm … > dd chose encore et faire une liste qui ressemble à

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

Parcourez maintenant la liste d'adresses - pour chaque entrée, trouvez l'entrée correspondante dans la liste des vidéos. Créez une nouvelle liste qui ressemble à une collection de lignes comme

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

Le x (numéro de lien symbolique) est remplacé par le numéro de séquence dans la liste d'adresses.

Vous avez maintenant une règle udev qui fonctionne. Un lien symbolique lié à une adresse de concentrateur USB, quel que soit le numéro vidéo attribué à ce port au démarrage.

Écrivez la liste finale dans un fichier /etc/udev/rules.d/cam.rules. Courir udevadm trigger pour l'activer et le travail est terminé. /dev/camera2 sera le même appareil photo (port USB) quel que soit son numéro de vidéo.

11
Ian Boag

J'ai également pu trouver un appareil unique dans /dev/serial/by-id. Je n'ai pas encore essayé de redémarrer, mais les fichiers de ce répertoire n'étaient que des liens vers le fichier de périphérique approprié (ttyACM[0-9]). `

J'utilise Arch Linux sur Raspberry Pi, mais je suis tombé dessus juste en faisant un find pour les noms de fichiers contenant "Arduino". Mes python fonctionnent bien en utilisant ces fichiers comme périphériques pour lire/écrire des données vers/depuis mes Arduinos (jusqu'à présent, deux sur un seul Pi).

1
huey_driver

Juste pour dire que ce qui précède a fonctionné pour moi et a également monté automatiquement l'appareil pour moi après avoir placé une entrée dans/etc/fstab (et il appelle également umount après le retrait du bâton)

c'est à dire.

/ 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"

Donc, après avoir inséré ma clé USB, je reçois:

root:# mount | grep sd
/dev/sda1 on /vol/backup type ext4 (rw,relatime,errors=remount-ro,data=ordered)
0
Will