it-swarm.com.de

Wie lese / schreibe ich auf tty * Gerät?

Ich habe ein Gerät, das Informationen über USB an meinen Computer sendet. Arch Linux richtet dieses Gerät ein, indem es in ttyUSB0 Eine Datei mit dem Namen /dev/ Erstellt. Ich habe GTKterm verwendet, um diese eingehenden Informationen zu empfangen und in einem emulierten Terminalfenster anzuzeigen.

Meine Frage ist, wie genau GTKterm diese ttyUSB0 - Datei liest/schreibt und wo ich anfangen kann, ähnliche Funktionen zu implementieren. Das heißt, in der einfachsten Form, wie kann ich ein Zeichen in ttyUSB0 Schreiben oder im Gegensatz dazu ein Byte empfangen und in eine Datei schreiben?

35
sherrellbc

TTYs sind Dateien, die Sie wie alle anderen verwenden können. Sie können sie mit den Standardwerkzeugen zum Öffnen von Dateien Ihrer Sprache öffnen und daraus lesen oder schreiben. Sie haben ein spezielles Verhalten, das sich von "normalen" Dateien unterscheidet, aber die Grundlagen sind dieselben. Ich werde am Ende einige der Sonderfälle behandeln, aber zuerst ein Experiment.

Eine interessante Sache, die Sie direkt von einem normalen Terminal aus erledigen können. Führen Sie tty aus und es wird eine Zeile wie folgt gedruckt:

/dev/pts/2

Das ist das TTY-Gerät, auf dem Ihr Terminal ausgeführt wird. Sie können etwas in dieses Terminal schreiben:

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

Sie können sogar daraus lesen:

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

(read X Ist shs Befehl "Zeile von Standardeingabe in Variable X lesen"; <soll/dev/pts/2 als Standardeingabe für den Lesebefehl verwenden; das erste "Hallo", das ich eingegeben habe, und der zweite wurde ausgedruckt).

Wenn Sie eine andere Shell öffnen, z. B. mit screen oder xterm, können Sie in dieser Shell run echo spooky > /dev/pts/2 Ausführen, damit der Text auf Ihrem ursprünglichen Terminal angezeigt wird für die anderen Befehle. All dies ist nur Ihre Shell, die eine Datei öffnet, ohne zu wissen, dass es sich um eine TTY handelt.


Hier ist ein sehr einfaches C-Programm, das genau das tut, was Sie gefragt haben, ein einzelnes Zeichen in/dev/pts/3 schreibt und dann ein einzelnes Byte zurückliest:

#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;
}

Ein echtes TTY-Gerät, das an eine Shell oder einen Terminalemulator angeschlossen ist, weist dort ein interessantes Verhalten auf, aber Sie sollten etwas zurückbekommen.


Um auf ein Terminal zugreifen zu können, benötigen Sie die Berechtigung, es zu verwenden. Dies sind nur die Standarddateiberechtigungen, die Sie mit ls -l Sehen und mit chmod festlegen: Sie benötigen eine Leseberechtigung, um die Datei zu öffnen und zu lesen, und eine Schreibberechtigung, um in sie zu schreiben. Die TTYs, die Ihr Terminal unterstützen, gehören Ihnen, die TTY eines anderen Benutzers jedoch nicht, und TTYs für USB-Geräte können je nach Konfiguration vorhanden sein oder nicht. Sie können die Berechtigungen wie immer ändern.

Wenn Sie ein Programm schreiben möchten, um damit zu arbeiten, müssen Sie nicht viel Besonderes tun. Sie können im Beispiel sehen, dass Sie nicht die Datei jedes Mal schließen müssen, damit Ihre Daten am anderen Ende gelesen werden: Die TTY-Dateien verhalten sich wie Pipelines und verschieben die Daten beim Eingang einfach in beide Richtungen. Als ich Text in das TTY schrieb, erschien er sofort, und als ich danach daraus las, wartete noch nichts auf mich. Es ist nicht so, als würde man in eine reguläre Datei schreiben, in der die Daten auf der Festplatte gespeichert werden - sie werden sofort an die andere Seite weitergeleitet oder bis zu einer Person im Speicher gespeichert liest es.

Möglicherweise möchten Sie die Funktion select verwenden, damit Sie andere Dinge tun können, während Sie darauf warten, dass das Gerät etwas sagt. Wenn Sie jedoch nur darauf warten möchten, dass Daten eingehen, können Sie sie einfach verwenden Blockieren von Lesevorgängen und Lassen Sie das Betriebssystem das Heben durchführen.

Eine Sache zu beachten ist, dass es eine begrenzte Puffergröße im Kernel geben kann, und wenn Sie viele Daten gleichzeitig schreiben, können Sie am Ende blockieren, ohne es zu wollen. Wenn dies wahrscheinlich ein Problem ist, verwenden Sie nicht blockierende E/A mit open("/dev/...", O_RDWR | O_NONBLOCK). Das Prinzip wird in beiden Fällen dasselbe sein.

43
Michael Homer