Port série virtuel pour Linux
je dois tester une application de port série sur Linux, cependant, ma machine de test n'a qu'un seul port série.
y a-t-il un moyen d'ajouter un port série virtuel à Linux et de tester mon application en émulant un périphérique à travers un shell ou un script?
Note: Je ne peux pas refaire le port, il est codé dur sur ttys2 et je dois tester l'application telle qu'elle est écrite.
8 réponses
Vous pouvez utiliser un pty ("pseudo-teletype", où un port série est un "vrai teletype") pour cela. D'un côté, ouvrez /dev/ptyp5
, puis attachez votre programme à /dev/ttyp5
; ttyp5
agira comme un port série, mais enverra/recevra tout ce qu'il fait via /dev/ptyp5.
si vous en avez vraiment besoin pour parler à un fichier appelé /dev/ttys2
, alors déplacez simplement votre ancien /dev/ttys2
et faites un lien symbolique de ptyp5
à ttys2
.
bien sûr, vous pouvez utiliser un numéro autre que ptyp5
. Peut-être en choisir un avec un nombre élevé pour éviter les doublons, puisque tous vos terminaux de connexion utiliseront aussi ptys.
Wikipedia a plus sur ptys: http://en.wikipedia.org/wiki/Pseudo_terminal
en complément de la réponse de @slonik.
vous pouvez tester socat pour créer un Port série virtuel en suivant la procédure suivante (testé sur Ubuntu 12.04):
ouvrez un terminal (appelons-le Terminal 0) et exécutez-le:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
le code ci-dessus renvoie:
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs [3,3] and [5,5]
ouvrir un autre terminal et écrire (Terminal 1):
cat < /dev/pts/2
le nom de port de cette commande peut être modifié selon le pc. il dépend de la sortie précédente.
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**2**
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/**3**
2013/11/01 13:47:27 socat[2506] N starting data transfer loop with FDs
, vous devez utiliser le numéro disponible sur la zone en surbrillance.
ouvrir un autre terminal et écrire (Terminal 2):
echo "Test" > /dev/pts/3
maintenant Retour au Terminal 1 et vous verrez la chaîne de caractères "Test".
utiliser socat pour ceci:
par exemple:
socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11
il y a aussi tty0tty http://sourceforge.net/projects/tty0tty / qui est un vrai émulateur de modem nul pour linux.
c'est un simple module du noyau - un petit fichier source. Je ne sais pas pourquoi il n'y a que le pouce vers le bas sur sourceforge, mais il fonctionne bien pour moi. La meilleure chose à ce sujet est qu'il émule également les pins matérielles (RTC/CTS DSR/DTR). Il implémente même les commandes TIOCMGET/TIOCMSET et TIOCMIWAIT iotcl!
sur un noyau récent vous pourriez avoir des erreurs de compilation. C'est facile à corriger. Il suffit d'insérer quelques lignes en haut du module/tty0tty.c source (après les inclu s):
#ifndef init_MUTEX
#define init_MUTEX(x) sema_init((x),1)
#endif
Lorsque le module est chargé, il crée 4 paires de ports série. Les appareils sont / dev /TNO to/dev / TNO 7 où TNO est connecté à tni1, tni2 est connecté à tni3, etc. Vous devrez peut-être corriger les permissions des fichiers pour pouvoir utiliser les périphériques.
edit:
I pense que j'ai été un peu rapide dans mon enthousiasme. Bien que le pilote semble prometteur, il semble instable. Je n'en suis pas sûr, mais je pense qu'il a planté une machine dans le bureau sur lequel je travaillais de chez moi. Je ne peux pas vérifier jusqu'à ce que je suis de retour au bureau le lundi.
la deuxième chose est que TIOCMIWAIT ne fonctionne pas. Le code semble être copié à partir d'un petit exemple de code "tty". Le maniement de TIOCMIWAIT semble en place, mais il ne se réveille jamais parce que l'appel correspondant à wake_up_interruptible() est manquant.
edit:
l'accident dans le bureau était vraiment la faute du conducteur. Il manquait une initialisation, et le code TIOCMIWAIT non testé a causé un crash de la machine.
j'ai passé hier et aujourd'hui à réécrire le conducteur. Il y avait beaucoup de problèmes, mais maintenant ça marche bien pour moi. Il manque encore du code pour le contrôle du flux matériel géré par le pilote, mais je n'en ai pas besoin. parce que je vais gérer les pins moi-même en utilisant TIOCMGET/TIOCMSET/TIOCMIWAIT à partir du code de mode utilisateur.
Si quelqu'un est intéressé, dans ma version du code, envoyez-moi un message et je vais vous l'envoyer.
vous pouvez regarder Tibbo VSPDL pour créer un port série virtuel linux en utilisant un pilote de noyau -- il semble assez nouveau, et est disponible en téléchargement dès maintenant (version bêta). Pas sûr de la licence à ce stade, ou s'ils veulent la rendre disponible commercialement que dans l'avenir.
il existe d'autres alternatives commerciales, telles que http://www.ttyredirector.com / .
In Open Source, Remserial (GPL) peut aussi faire ce que vous voulez, en utilisant Unix PTY. Il transmet les données de série sous "forme brute" à une socket de réseau; la configuration STTY-like des paramètres de terminal doit être faite lors de la création du port, les changer plus tard comme décrit dans la RFC 2217 ne semble pas être supporté. Vous devriez être capable d'exécuter deux instances remserial pour créer un nullmodem virtuel comme com0com, sauf que vous aurez besoin de configurer la vitesse du port etc à l'avance.
Socat (aussi GPL) est comme une variante étendue de Remserial avec beaucoup plus d'options, y compris une méthode " PTY " pour rediriger le PTY à quelque chose d'autre, qui peut être une autre instance de Socat. Pour Unit tets, socat est probablement plus agréable que remserial parce que vous pouvez directement cat fichiers dans le PTY. Voir le exemple PTY sur la page de manuel. Un patch existe sous "contrib" pour fournir un soutien RFC2217 pour la négociation série de paramètres de la ligne.
en utilisant les liens affichés dans les réponses précédentes, j'ai codé un petit exemple en C++ en utilisant un Port série virtuel. J'ai mis le code dans GitHub: https://github.com/cymait/virtual-serial-port-example .
Le code est assez explicite. Tout d'abord, vous créez le processus maître en exécutant ./main de maître et il s'imprime sur la sortie stderr l'appareil utilise. Après cela, vous appeler ./esclave, où périphérique est le dispositif imprimé dans le premier commandement.
Et c'est tout. Vous avez un lien bidirectionnel entre les deux processus.
en utilisant cet exemple, vous pouvez tester l'application en envoyant toutes sortes de données, et voir si cela fonctionne correctement.
en outre, vous pouvez toujours faire un lien symbolique avec l'appareil, de sorte que vous n'avez pas besoin de recompiler l'application que vous testez.
seriez-vous capable d'utiliser un adaptateur USB - >RS232? J'en ai quelques-uns, et ils utilisent juste le conducteur FTDI. Ensuite, vous devriez être capable de renommer /dev/ttyUSB0 (ou ce qui est créé) comme /dev/ttyS2 .
je ne peux penser à trois options:
mettre en Œuvre la RFC 2217
RFC 2217 couvre un port com à la norme TCP/IP qui permet à un client sur un système d'émuler un port série aux programmes locaux, tout en envoyant et en recevant de manière transparente des données et des signaux de contrôle à un serveur sur un autre système qui a réellement le port série. Voici un aperçu de haut niveau .
Ce que vous il s'agirait de trouver ou d'implémenter un pilote de port com client qui implémenterait le côté client du système sur votre PC - semblant être un vrai port série mais en réalité tout faire pivoter vers un serveur. Vous pourriez être en mesure d'obtenir ce pilote gratuitement de Digi, Lantronix, etc à l'appui de leurs véritables serveurs de port série autonomes.
vous implémentez alors le côté serveur de la connexion localement dans un autre programme - permettant au client de se connecter et d'émettre commandes de données et de contrôle au besoin.
c'est probablement non trivial, mais le RFC est là, et vous pourriez être en mesure de trouver un projet open source qui implémente un ou deux côtés de la connexion.
modifier le pilote du port série linux
alternativement, la source du pilote de port série Pour Linux est facilement disponible. Prenez ça, videz les pièces de contrôle matériel, et demandez à ce qu'un pilote exécute deux ports / dev/ ttySx, bouclage. Puis connectez votre vrai programme au ttyS2 et votre simulateur à l'autre ttySx.
utiliser deux câbles USB<-->série dans un loopback
Mais la chose la plus facile à faire maintenant? Dépensez 40 $sur deux port série USB, les connecter ensemble (null modem) et ont en fait deux ports série réel - un pour le programme que vous testez, un pour votre simulateur.
- Adam