Comment lire / écrire sur un appareil tty *?


29

J'ai un appareil qui envoie des informations via USB à mon ordinateur. Arch Linux configure cet appareil en créant un fichier nommé ttyUSB0dans /dev/. J'utilise GTKtermpour recevoir ces informations entrantes et les afficher dans une fenêtre de terminal émulée.

Ma question est la suivante: comment exactement GTKtermlire / écrire dans ce ttyUSB0fichier et où puis-je commencer à apprendre comment implémenter des fonctionnalités similaires? C'est-à-dire, dans la forme la plus élémentaire, comment pourrais-je écrire un caractère ttyUSB0ou, au contraire, recevoir un octet et l'écrire dans un fichier?


1
Essayez d'utiliser cat pour lire et faire écho pour écrire. "Tout est un fichier" sous unix :)
dchirikov

Vous pouvez essayer d'ouvrir une console série dessus. screenpeut le faire, etminiterm
mikeserv

Je pensais en termes d'approche programmatique. Si cela est vrai et que c'est vraiment aussi simple (ouvrir et lire le fichier), écririez-vous simplement une boucle infinie pour ouvrir, lire, fermer le fichier et mettre à jour en continu lorsque de nouvelles données sont présentes depuis la dernière fois? Que se passe-t-il si le périphérique «tty» tente d'écrire dans le fichier si vous l'avez ouvert dans votre programme?
sherrellbc

Cela peut être utile: cmrr.umn.edu/~strupp/serial.html : open (), read (), write () et select (). Rien de spécial, semble-t-il.
dchirikov

@sherrellbc - vous pouvez écrire un script screenet / ou par minitermprogrammation.
mikeserv

Réponses:


38

Les ATS sont des fichiers que vous pouvez utiliser comme n'importe quel autre. Vous pouvez les ouvrir avec les outils standard d'ouverture de fichier de votre langue et lire ou écrire à partir d'eux. Ils ont un comportement spécial différent des fichiers "ordinaires", mais les bases sont les mêmes. Je couvrirai certains des cas spéciaux à la fin, mais d'abord, une expérience.

Une chose intéressante que vous pouvez faire directement depuis un terminal ordinaire. Exécutez ttyet il imprimera une ligne comme:

/dev/pts/2

C'est l'appareil TTY sur lequel votre terminal fonctionne. Vous pouvez écrire quelque chose sur ce terminal:

$ echo Hello > /dev/pts/2
Hello
$

Vous pouvez même en lire:

$ read X < /dev/pts/2
hello
$ echo $X
hello
$

( read Xest la commande "lire une ligne de l'entrée standard dans la variable X" de sh; le <consiste à utiliser / dev / pts / 2 comme entrée standard pour la commande de lecture; le premier "bonjour" que j'ai tapé et le second a été imprimé) .

Si vous ouvrez un autre shell, par exemple en utilisant screenou xterm, vous pouvez exécuter run echo spooky > /dev/pts/2dans ce shell pour faire apparaître le texte sur votre terminal d'origine, et la même chose pour les autres commandes. Tout cela n'est que votre shell ouvrant un fichier sans savoir qu'il s'agit d'un ATS.


Voici un programme C très simple qui fait exactement ce que vous avez demandé et écrit un seul caractère dans / dev / pts / 3, puis en lit un seul octet:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>    
int main() {
    char byte;
    int fd = open("/dev/pts/3", O_RDWR);
    write(fd, "X", 1);
    ssize_t size = read(fd, &byte, 1);
    printf("Read byte %c\n", byte);
    return 0;
}

Un véritable appareil TTY attaché à un shell ou à un émulateur de terminal aura un comportement intéressant, mais vous devriez récupérer quelque chose.


Pour accéder à un terminal, vous devez être autorisé à l'utiliser. Ce ne sont que les autorisations de fichier standard que vous voyez ls -let définissez avec chmod: vous avez besoin d'une autorisation de lecture pour ouvrir le fichier et le lire, et une autorisation d'écriture pour y écrire. Les ATS qui soutiennent votre terminal vous appartiendront, mais pas ceux d'un autre utilisateur, et les ATS pour les périphériques USB peuvent ou non l'être, selon votre configuration. Vous pouvez modifier les autorisations de la même manière que toujours.

En ce qui concerne l'écriture d'un programme pour travailler avec lui, vous n'avez pas besoin de faire beaucoup de spécial. Vous pouvez voir dans l'exemple qu'une chose que vous n'avez pas besoin de faire est de fermer le fichier à chaque fois pour que vos données soient lues à l'autre extrémité: les fichiers TTY agissent comme des pipelines, poussant simplement les données dans les deux directions à mesure qu'elles entrent. Quand j'ai écrit du texte sur le TTY, il est apparu immédiatement, et quand je l'ai lu par la suite, rien ne m'attendait déjà. Ce n'est pas comme écrire dans un fichier normal où les données sont enregistrées sur le disque - elles sont transmises immédiatement de l'autre côté ou stockées en mémoire jusqu'à ce que quelqu'un les lise.

Vous voudrez peut-être utiliser la fonction de sélection pour pouvoir faire d'autres choses en attendant que l'appareil dise quelque chose, mais si vous êtes content d'attendre que les données passent, vous pouvez simplement utiliser des lectures de blocage et laisser le système d'exploitation faire le levage.

Une chose à garder à l'esprit est qu'il peut y avoir une taille de tampon limitée dans le noyau, et si vous écrivez beaucoup de données à la fois, vous pouvez finir par bloquer sans le vouloir. Si cela est susceptible d'être un problème, utilisez des E / S non bloquantes avec open("/dev/...", O_RDWR | O_NONBLOCK). Le principe sera le même dans les deux cas.


Je suis en train sudo echo Hello > /dev/tty4quand je suis dans l'environnement de bureau , mais je reçois bash: /dev/tty4: Permission deniedsi je ne suis pas connecté à tty4. Cependant, si je suis connecté à tty4, tout fonctionne bien. Quelle est la raison pour ça?
Utku

@Utku, C'est certainement une sorte de problème d'autorisations qui est supprimé après l'authentification avec le terminal virtuel. Vérifiez les autorisations de fichier avant et après vous être connecté.ls -l /dev/tty4
sherrellbc

1
la > /dev/tty4partie n'est pas une partie du echosous - processus démarré par sudomais une partie du sudoprocessus lui-même, qui est exécuté par l'utilisateur actuel. les autorisations de fichier pour l'utilisateur actuel s'appliquent à la place de root.
Robin479
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.