Quelle est la bonne façon d'obtenir une liste de tous les ports / périphériques série disponibles sur un système Linux?
En d'autres termes, lorsque j'effectue une itération sur tous les périphériques /dev/
, comment puis-je savoir quels sont les ports série de manière classique, c'est-à-dire ceux qui prennent généralement en charge les débits en bauds et le contrôle de flux RTS / CTS ?
La solution serait codée en C.
Je demande parce que j'utilise une bibliothèque tierce qui fait clairement cela mal: il semble seulement itérer /dev/ttyS*
. Le problème est qu'il existe, par exemple, des ports série via USB (fournis par des adaptateurs USB-RS232), et ceux-ci sont répertoriés sous / dev / ttyUSB *. Et lire le Serial-HOWTO sur Linux.org , j'ai l'idée qu'il y aura aussi d'autres espaces de noms, avec le temps.
J'ai donc besoin de trouver le moyen officiel de détecter les périphériques série. Le problème est qu'aucun ne semble être documenté, ou je ne le trouve pas.
J'imagine qu'une façon serait d'ouvrir tous les fichiers /dev/tty*
et d'en appeler un spécifique ioctl()
qui n'est disponible que sur les périphériques série. Serait-ce une bonne solution, cependant?
Mettre à jour
hrickards suggéré de regarder la source de "setserial". Son code fait exactement ce que j'avais en tête:
Tout d'abord, il ouvre un appareil avec:
fd = open (path, O_RDWR | O_NONBLOCK)
Ensuite, il invoque:
ioctl (fd, TIOCGSERIAL, &serinfo)
Si cet appel ne renvoie aucune erreur, alors c'est un périphérique série, apparemment.
J'ai trouvé un code similaire dans la programmation série / termios , ce qui suggérait d'ajouter également l' O_NOCTTY
option.
Il y a cependant un problème avec cette approche:
Lorsque j'ai testé ce code sur BSD Unix (c'est-à-dire Mac OS X), cela a également fonctionné. Cependant , les périphériques série fournis via Bluetooth obligent le système (pilote) à essayer de se connecter au périphérique Bluetooth, ce qui prend un certain temps avant qu'il ne revienne avec une erreur de temporisation. Cela est dû à la simple ouverture de l'appareil. Et je peux imaginer que des choses similaires peuvent également se produire sous Linux - idéalement, je ne devrais pas avoir besoin d'ouvrir l'appareil pour déterminer son type. Je me demande s'il existe également un moyen d'invoquer des ioctl
fonctions sans ouvrir ou d'ouvrir un périphérique de manière à ne pas créer de connexions?
Que devrais-je faire?
la source
Réponses:
Le
/sys
système de fichiers devrait contenir de nombreuses informations pour votre quête. Mon système (2.6.32-40-generic # 87-Ubuntu) suggère:Ce qui vous donne une description de tous les appareils TTY connus du système. Un exemple réduit:
En suivant l'un de ces liens:
Ici, le
dev
fichier contient ces informations:C'est le nœud majeur / mineur. Ceux-ci peuvent être recherchés dans le
/dev
répertoire pour obtenir des noms conviviaux:Le
/sys/class/tty
répertoire contient tous les périphériques TTY, mais vous voudrez peut-être exclure ces terminaux virtuels et pseudo terminaux. Je vous suggère d'examiner uniquement ceux qui ont unedevice/driver
entrée:la source
/dev/zero
. Pensez-vous vraiment qu'il s'agit d'un périphérique série?Dans les noyaux récents (je ne sais pas depuis quand), vous pouvez lister le contenu de / dev / serial pour obtenir une liste des ports série de votre système. Ce sont en fait des liens symboliques pointant vers le bon nœud / dev /:
Il s'agit d'un adaptateur USB-série, comme vous pouvez le voir. Notez que lorsqu'il n'y a pas de port série sur le système, le répertoire / dev / serial / n'existe pas. J'espère que cela t'aides :).
la source
Je fais quelque chose comme le code suivant. Cela fonctionne pour les périphériques USB et aussi les stupides périphériques serial8250 dont nous avons tous 30 - mais seuls quelques-uns d'entre eux fonctionnent vraiment.
Fondamentalement, j'utilise le concept des réponses précédentes. Commencez par énumérer tous les périphériques tty dans / sys / class / tty /. Les périphériques qui ne contiennent pas de sous-répertoire / device sont filtrés. / sys / class / tty / console est un tel périphérique. Ensuite, les périphériques contenant réellement un périphérique sont alors acceptés comme port série valide en fonction de la cible du pilote-lien symbolique fx.
et pour ttyS0
Tous les pilotes pilotés par serial8250 doivent être des sondes utilisant l'ioctl mentionné précédemment.
Seul le port signalant un type de périphérique valide est valide.
La source complète d'énumération des ports série ressemble à ceci. Les ajouts sont les bienvenus.
la source
Je pense avoir trouvé la réponse dans ma documentation source du noyau: /usr/src/linux-2.6.37-rc3/Documentation/filesystems/proc.txt
Voici un lien vers ce fichier: http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=blob_plain;f=Documentation/filesystems/proc.txt;hb = e8883f8057c0f7c9950fa9f20568f37bfa62f34a
la source
j'ai trouvé
faire le travail.
la source
setserial avec l'option -g semble faire ce que vous voulez et la source C est disponible à http://www.koders.com/c/fid39344DABD14604E70DF1B8FEA7D920A94AF78BF8.aspx .
la source
Je n'ai pas de périphérique série ici pour le tester, mais si vous avez python et dbus, vous pouvez l'essayer vous-même.
En cas d'échec, vous pouvez rechercher à l'intérieur
hwmanager_i.GetAllDevicesWithProperties()
pour voir si le nom de capacité «série» que je viens de deviner a un nom différent.HTH
la source
Je n'ai pas de périphérique série USB, mais il doit y avoir un moyen de trouver les ports réels en utilisant directement les bibliothèques HAL:
Le code python-dbus publié ni ce script sh ne répertorie les périphériques bluetooth / dev / rfcomm *, ce n'est donc pas la meilleure solution.
Notez que sur les autres plates-formes unix, les ports série ne sont pas nommés ttyS? et même sous Linux, certaines cartes série vous permettent de nommer les appareils. En supposant qu'un modèle dans les noms des périphériques série est incorrect.
la source
L'utilisation de / proc / tty / drivers indique uniquement quels pilotes tty sont chargés. Si vous recherchez une liste des ports série check out / dev / serial, il aura deux sous-répertoires: by-id et by-path.
EX:
Merci à ce post: /superuser/131044/how-do-i-know-which-dev-ttys-is-my-serial-port
la source
Mon approche via la numérotation de groupe pour obtenir chaque tty avec l'utilisateur `` dialout ''
ls -l /dev/tty* | grep 'dialout'
pour obtenir uniquement son dossierls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev
écoute facile de la sortie tty, par exemple quand une sortie série arduino:
head --lines 1 < /dev/ttyUSB0
écoutez chaque tty sur une seule ligne:
for i in $(ls -l /dev/tty* | grep 'dialout' | rev | cut -d " " -f1 | rev); do head --lines 1 < $i; done
J'aime beaucoup l'approche via la recherche de pilotes:
ll /sys/class/tty/*/device/driver
Vous pouvez choisir le tty-Name maintenant:
ls /sys/class/tty/*/device/driver | grep 'driver' | cut -d "/" -f 5
la source
La bibliothèque du gestionnaire de communication série comprend de nombreuses API et fonctionnalités ciblées pour la tâche souhaitée. Si l'appareil est un USB-UART, son VID / PID peut être utilisé. Si le périphérique est BT-SPP, des API spécifiques à la plate-forme peuvent être utilisées. Jetez un œil à ce projet pour la programmation du port série: https://github.com/RishiGupta12/serial-communication-manager
la source
oui, je sais, je suis trop tard (comme toujours). Voici mon morceau de code (basé sur la réponse de mk2). Peut-être que cela aide quelqu'un:
la source