Question

Je dois tester une application de port série sous Linux, cependant, ma machine de test ne dispose que d'un seul port série.

Existe-t-il un moyen d'ajouter un port série virtuel à Linux et de tester mon application en émulant un périphérique via un shell ou un script ?

Note:Je ne peux pas remapper le port, il est codé en dur sur ttys2 et je dois tester l'application telle qu'elle est écrite.

Était-ce utile?

La solution

Vous pouvez utiliser un pty ("pseudo-télétype", où un port série est un "vrai télétype") pour cela.D'une extrémité, 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, puis déplacez simplement votre ancien /dev/ttys2 à l'écart et créez un lien symbolique à partir de ptyp5 à ttys2.

Bien sûr, vous pouvez utiliser un numéro autre que ptyp5.Choisissez-en un avec un nombre élevé pour éviter les doublons, car tous vos terminaux de connexion utiliseront également des ptys.

Wikipédia en dit plus sur les ptys : http://en.wikipedia.org/wiki/Pseudo_terminal

Autres conseils

Complétant la réponse de @slonik.

Vous pouvez tester socat pour créer un port série virtuel en suivant la procédure suivante (testée 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]

Ouvrez un autre terminal et écrivez (Terminal 1) :

cat < /dev/pts/2

le nom du port de cette commande peut être modifié en fonction du PC.cela 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 dans la zone en surbrillance.

Ouvrez un autre terminal et écrivez (Terminal 2) :

echo "Test" > /dev/pts/3

Revenons maintenant au terminal 1 et vous verrez la chaîne « Test ».

Utilisez socat pour cela :

Par exemple:

socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11

Il y a aussi tty0tty http://sourceforge.net/projects/tty0tty/ qui est un véritable émulateur null modem pour Linux.

Il s'agit d'un simple module de noyau - un petit fichier source.Je ne sais pas pourquoi Sourceforge n'a eu que des critiques négatives, mais cela fonctionne bien pour moi.La meilleure chose à ce sujet est qu'il émule également les broches matérielles (RTC/CTS DSR/DTR).Il implémente même les commandes iotcl TIOCMGET/TIOCMSET et TIOCMIWAIT !

Sur un noyau récent, vous risquez d'avoir des erreurs de compilation.C'est facile à réparer.Insérez simplement quelques lignes en haut du source module/tty0tty.c (après les inclusions) :

#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 périphériques sont /dev/tnt0 à /dev/tnt7 où tnt0 est connecté à tnt1, tnt2 est connecté à tnt3, etc.Vous devrez peut-être corriger les autorisations de fichiers pour pouvoir utiliser les appareils.

modifier:

Je suppose que j'ai été un peu rapide avec mon enthousiasme.Bien que le pilote semble prometteur, il semble instable.Je n'en suis pas sûr, mais je pense qu'une machine est tombée en panne dans le bureau sur lequel je travaillais depuis chez moi.Je ne peux pas vérifier avant mon retour au bureau lundi.

La deuxième chose est que TIOCMIWAIT ne fonctionne pas.Le code semble être copié à partir d'un exemple de code "minuscule tty".La gestion de TIOCMIWAIT semble en place, mais elle ne se réveille jamais car l'appel correspondant à wake_up_interruptible() est manquant.

modifier:

L'accident au bureau était en réalité la faute du conducteur.Il manquait une initialisation et le code TIOCMIWAIT complètement non testé a provoqué un crash de la machine.

J'ai passé hier et aujourd'hui à réécrire le pilote.Il y a eu beaucoup de problèmes, mais maintenant ça marche bien pour moi.Il manque encore du code pour le contrôle de flux matériel géré par le pilote, mais je n'en ai pas besoin car je vais gérer moi-même les broches en utilisant TIOCMGET/TIOCMSET/TIOCMIWAIT à partir du code du mode utilisateur.

Si quelqu'un est intéressé par ma version du code, envoyez-moi un message et je vous l'enverrai.

Vous voudrez peut-être regarder Tibbo VSPDL pour créer un port série virtuel Linux à l'aide d'un pilote Kernel - cela semble assez nouveau et est disponible en téléchargement dès maintenant (version bêta).Je ne suis pas sûr de la licence à ce stade, ni s'ils souhaitent la rendre disponible dans le commerce uniquement à l'avenir.

Il existe d'autres alternatives commerciales, telles que http://www.ttyredirector.com/.

En Open Source, Remsérie (GPL) peut également faire ce que vous voulez, en utilisant les PTY d'Unix.Il transmet les données série sous « forme brute » vers une prise réseau ;Une configuration de type STTY des paramètres du terminal doit être effectuée lors de la création du port, leur modification ultérieure comme décrit dans la RFC 2217 ne semble pas être prise en charge.Vous devriez pouvoir exécuter deux instances remserial pour créer un nullmodem virtuel comme com0com, sauf que vous devrez configurer la vitesse du port, etc. à l'avance.

Socat (également GPL) est comme une variante étendue de Remserial avec beaucoup plus d'options, y compris une méthode "PTY" pour rediriger le PTY vers autre chose, qui peut être une autre instance de Socat.Pour les unités tets, socat est probablement plus agréable que remserial car vous pouvez directement cat fichiers dans le PTY.Voir le Exemple PTY sur la page de manuel.UN le patch existe sous « contrib » pour fournir la prise en charge RFC2217 pour la négociation des paramètres de ligne série.

En utilisant les liens posté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 poussé 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 master et il s’imprimera sur stderr que le périphérique utilise.Après cela, vous invoquez ./main slave device, où périphérique est le périphérique imprimé dans la première commande.

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 elle fonctionne correctement.

De plus, vous pouvez toujours créer un lien symbolique vers l'appareil, vous n'avez donc 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 simplement le pilote FTDI.Ensuite, vous devriez pouvoir renommer /dev/ttyUSB0 (ou tout ce qui est créé) en /dev/ttyS2 .

Je peux penser à trois options :

Implémenter la RFC 2217

RFC2217 couvre un port COM conforme à la norme TCP/IP qui permet à un client d'un système d'émuler un port série pour les 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 possède réellement le port série.Voici un aperçu de haut niveau.

Ce que vous feriez est 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 - ressemblant à un véritable port série mais en réalité transférant tout vers un serveur.Vous pourrez peut-être obtenir ce pilote gratuitement auprès de Digi, Lantronix, etc. pour prendre en charge leurs véritables serveurs de port série autonomes.

Vous implémenterez ensuite le côté serveur de la connexion localement dans un autre programme - permettant au client de se connecter et d'émettre les données et les commandes de contrôle selon les besoins.

Ce n'est probablement pas trivial, mais la RFC existe et vous pourrez peut-être trouver un projet open source qui implémente un ou les 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 cela, videz les éléments de contrôle matériels et demandez à ce pilote d'exécuter deux ports /dev/ttySx, comme un simple bouclage.Connectez ensuite votre vrai programme au ttyS2 et votre simulateur à l'autre ttySx.

Utilisez deux câbles USB<-->Série dans un bouclage

Mais la chose la plus simple à faire en ce moment ?Dépensez 40 $ pour deux périphériques USB à port série, connectez-les ensemble (modem nul) et disposez en fait de deux vrais ports série - un pour le programme que vous testez, un pour votre simulateur.

-Adam

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top