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

44

J'ai un Arduino qui est parfois lié à d' /dev/ttyUSB0autres 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érerais qu'il soit lié à un endroit statique, par exemple /dev/arduino.

Comment puis-je y arriver?

k0pernikus
la source
4
Il suffit d’écrire une simple règle udev qui assigne un lien symbolique / dev / arduino au bon inventé par son VID et son PID.
Eddy_Em
1
Après avoir modifié les règles, reportez-vous à la section Comment recharger des règles udev sans redémarrer?
Gilles 'SO, arrête d'être méchant'

Réponses:

42

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

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

Vous pouvez vérifier les variables de votre appareil en lançant

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

Il existe un guide plus détaillé que vous pouvez lire sur http://www.reactivated.net/writing_udev_rules.html

Kotte
la source
Travaillé comme un charme. Une question: comment sortir udevam? Et il est important de noter que my_uartcrée le lien symbolique sous /dev/my_uart. J'ai écrit /dev/arduinola première fois pour la première fois et ça a échoué tant que arduinoc'est suffisant.
K0pernikus
udevadmdevrait sortir par lui-même quand c'est fait.
Kotte
Puis, pour une raison inconnue, il a gelé la session de terminal sur mon Raspberry Pi lors de la génération du rapport.
K0pernikus
35

La syntaxe de la règle ci-dessus peut fonctionner sur certaines distributions, mais pas sur la mienne (Raspbian). Comme je n'ai jamais trouvé un seul document qui explique tous les tenants et les aboutissants, j'ai écrit le mien, à retrouver ici . C'est ce que cela revient à.
1. Découvrez ce qu'il y a sur ttyUSB:

dmesg | grep ttyUSB  

2. liste tous les attributs de l'appareil:

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

(avec votre numéro de périphérique (s) au lieu de x, bien sûr). Choisissez un ensemble d'identifiants uniques, par exemple idVendor + idProduct. Vous aurez peut-être également besoin du numéro de série si vous avez plusieurs périphériques avec les mêmes idVendor et idProduct. Les numéros de série doivent être uniques pour chaque périphérique.
3. Créez un fichier /etc/udev/rules.d/99-usb-serial.rulescontenant 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, et bien sûr des 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 le cas /dev/ttyUSB1, vérifiez ensuite à qui appartient ce groupe 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)
RolfBly
la source
Alors, y a-t-il une solution si le idVendoret idProductsont exactement les mêmes? (deux capteurs attachés sur des modules USB à UART de modèle identique)
Steven Lu le
@StevenLu Oui, reportez-vous à l'étape 2, procédez udevadm info --name=/dev/ttyUSB1 --attribute-walkcomme suit pour les deux périphériques et recherchez les numéros de série. Ils doivent être uniques pour chaque périphérique. Si vos capteurs n’ont pas de numéro de série, pouvez-vous les préciser?
RolfBly
c'est génial, je ferai un rapport lorsque j'essayerai ceci
Steven Lu
Mes dongles USB à UART $ 2 portent le numéro de série 0001. Je ne peux pas dire que je suis surpris. On dirait que je dois identifier les capteurs en fonction de leur protocole de sortie.
Steven Lu
@StevenLu Pas de chance. Les convertisseurs USB-UART FTDI ont un numéro de série unique, autant que je sache. Quelques dollars de plus, mais moins de temps pour se développer.
RolfBly
9

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

J'ai un Rasperry Pi avec quatre caméras. Je prends pix avec fswebcamqui identifie les caméras comme /dev/video0.. video3. Parfois , la caméra est video0, vide02, video4et video6mais nous pouvons oublier que pour l' instant.

J'ai besoin d'un identifiant persistant pour identifier un numéro de caméra, par exemple, video0c'est toujours la même caméra car je sous-titrai les images. Malheureusement, cela n’arrive pas de façon fiable: au démarrage, les caméras sont énumérées de la manière suivante video0video3mais pas toujours de la même manière.

Les caméras ont toutes le même ID et le même 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 lancez la commande

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

vous obtenez une table de sortie, mais les éléments saillants sont

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

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

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

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

Ça a l'air simple - accéder à 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 /dev/camera0dit en gros no such device. Carré un.

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

La première étape a été de courir

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

pour xentre 1 et 8. L'existence de tst.jpgaprè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. Mon expérience a été que c'est soit 0,1,2,3ou 0,2,4,6pour les appareils photo que j'ai utilisés.

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

Puis pour chaque numéro de vidéo dans la liste

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

et extraire le KERNELS= linede dd. A partir de ce processus, vous obtenez une liste d'adresses de ports USB pour les caméras. Triez cette liste de manière à la traiter toujours dans le même ordre à l'étape suivante. Appelez cela la "liste d'adresses".

Exécutez la udevadm … > ddchose à nouveau et faites 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, recherchez l'entrée correspondante dans la liste de 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.

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

Écrivez la liste finale dans un fichier /etc/udev/rules.d/cam.rules. Exécuter udevadm triggerpour l'activer et le travail est terminé. /dev/camera2sera la même caméra (port USB) quel que soit son numéro de vidéo.

Ian Boag
la source
Bienvenue sur unix stackexchange. Veuillez formater votre réponse en utilisant markdown. Je viens de le faire pour vous. N'oubliez pas non plus que nous voulons que les réponses soient pertinentes. Cela ressemble plus à une entrée de blog (ce qui n’est pas entièrement mauvais), mais il n’est pas très utile d’apprendre d’abord sur les approches qui n’ont pas fonctionné. Vous pouvez supprimer cette partie.
k0pernikus
Désolé. Je suis nouveau ici. J'ai étudié ce problème pendant des mois. J'ai trouvé d'autres personnes aux prises avec le même problème et je n'ai pas trouvé de réponse satisfaisante pour moi. Juste pour que je sache, où conseilleriez-vous que je poste quelque chose comme ça? Je me suis retenu et n'incluais pas la source Python :-)
Ian Boag
1

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 étaient simplement des liens vers le fichier de périphérique approprié ( ttyACM[0-9]) .`

Je suis en train de lancer arch linux sur Raspberry Pi, mais je suis tombé sur eux simplement en faisant un findpour les noms de fichiers contenant "Arduino". Mes programmes python fonctionnent correctement 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).

huey_driver
la source
0

Juste pour dire que ce qui précède a fonctionné pour moi et a également monté automatiquement le périphérique pour moi après avoir placé une entrée dans / etc / fstab (et cela appelle également umount après le retrait du stick)

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)
Volonté
la source