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, quand j'itère sur tous les dispositifs dans /dev/
comment puis-je savoir quels sont les ports série classiques, c'est-à-dire ceux qui supportent habituellement des vitesses de transmission et des vitesses d'échantillonnage ? RTS/CTS le contrôle des flux ?
La solution serait codée en C.
Je pose la question parce que j'utilise une bibliothèque tierce qui fait clairement fausse route : elle semble seulement itérer sur /dev/ttyS*
. Le problème est qu'il existe, par exemple, des ports série sur USB (fournis par des adaptateurs USB-RS232), et ceux-ci sont répertoriés sous /dev/ttyUSB*. Et en lisant le Serial-HOWTO à Linux.org J'ai l'impression qu'il y aura d'autres espaces de noms, le moment venu.
Je dois donc trouver le moyen officiel de détecter les périphériques série. Le problème est qu'aucune ne semble être documentée, ou je ne peux pas la trouver.
J'imagine qu'une solution serait d'ouvrir tous les fichiers à partir de /dev/tty*
et appeler un ioctl()
sur eux qui n'est disponible que sur les périphériques série. Est-ce que ce serait une bonne solution ?
Mise à jour
hrickards a suggéré de regarder la source de "setserial". Son code fait exactement ce que j'avais en tête :
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 _Programmation en série/termios_ qui a suggéré d'ajouter également le 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), il a également fonctionné. Cependant Dans le cas des périphériques série fournis par Bluetooth, le système (pilote) essaie de se connecter au périphérique Bluetooth, ce qui prend un certain temps avant de renvoyer une erreur de dépassement de délai. Ceci est causé par la simple ouverture du périphérique. Et je peux imaginer que des choses similaires peuvent se produire sous Linux également - idéalement, je ne devrais pas avoir besoin d'ouvrir le périphérique pour connaître son type. Je me demande s'il existe également un moyen d'invoquer ioctl
fonctionne sans ouverture, ou ouvre un dispositif de manière à ce qu'il ne provoque pas de connexions ?
Que dois-je faire ?
1 votes
Quelqu'un d'anonyme avait suggéré cette modification, qui a été rejetée, alors je la laisse ici en commentaire à la place : Si vous utilisez le drapeau TIOCGSERIAL dans l'appel ioctl, au lieu de TIOCMGET, alors l'appel ne renvoie pas d'erreur avec certains chemins erronés qui ne font pas référence à un port COM (série). Avec le drapeau TIOCMGET, ioctl ne fonctionne qu'avec les ports COM disponibles pour l'accès dans les chemins possibles TTY et TTYUSB.