weidner/computer/hardware/

Die serielle Schnittstelle bei Linux

Ich verwende die serielle (RS-232-)Schnittstelle schon mehr als 30 Jahre um mit anderen Geräten kommunizieren. Heutzutage sieht es zwar so aus, als würde sie von USB-Schnittstellen verdrängt, aber es gibt noch genügend Geräte, auf die ich nur mit einer seriellen Schnittstelle zugreifen kann. Router, Switche, die Rechner von PC Engines, ich habe einige Geräte, auf deren Konsole ich mit RS-232 zugreife.

Der Standard ist für eine Übertragungsrate von 20000 Bit/s gedacht, man spricht hier auch von Baudrate. Moderne UARTs (Universal Asynchronous Receiver Transmitter) unterstützen meist bis 115200 Bit/s. Da die Schnittstelle asynchron funktioniert, wird bei jeder Übertragung ein Start- und ein Stoppbit für die Synchronisation hinzugefügt. Zusammen mit 8 Datenbits und einer kleinen Pause zwischen zwei Byteübertragungen ist ein guter Näherungswert für die Byteübertragungsrate ein Zehntel der Baudrate.

Hardware

Am PC oder Laptop ist die serielle Schnittstelle mittlerweile schon selten anzutreffen, obwohl sie früher in fast jedem Gerät vorhanden war. Bei Desktop oder Tower-Rechnern kann ich manchmal eine Erweiterungskarte einbauen, wenn keine COM-Schnittstelle auf dem Mainboard verbaut ist.

Auf dem Laptop muss ich dann auf USB-Seriell-Wandler zurückgreifen.

Kabel

Bei modernen Geräten kann ich meist auf die Steuerung der Schnittstelle durch die Leitungen RTS (Ready-To-Send) beziehungs RTR (Ready-To-Receive) und CTS (Clear-To-Send) verzichten und komme dann mit drei Leitungen (TXD - Transmit Data, RXD - Receive Data, GND - Ground) aus. Das vereinfacht die Verkabelung.

Da bei RS-232 die Leitungen am Ende nicht mit dem Wellenwiderstand abgeschlossen werden, kommt es zu Reflexionen, was die maximale Datenübetragungsrate begrenzt. Der Standard verlangt, dass die Flanken der einzelnen Signale nicht steiler als 30 V/µs sind, um die Auswirkungen der Reflexionen zu begrenzen. Das ist der Hauptgrund für die Begrenzung der Bitübertragungsrate.

Außerdem werden die Signale nicht differentiell sondern asymmetrisch gesendet, so dass es zu Störungen bei der Übertragung kommen kann, weil sowohl Sende als auch Empfangsleitung die gleiche Rückleitung (GND) verwenden. Eine stärkere GND-Leitung (z.B. durch Verwenden mehrerer Adern) kann das Problem lindern, aber nicht eliminieren. Besser wäre eine differentielle Übertragung wie sie zum Beispiel bei RS-485 verwendet wird. Diese benötigt wiederum mehr Adern zur Übertragung.

Laut dem Wikipedia-Artikel sollte ich daher bei 115200 Baud ein Kabel verwenden, dass kürzer als zwei Meter ist. Mit geringeren Baudraten kann ich längere Leitungen verwenden.

Treiber

Mit Linux brauche ich mir keine Gedanken über die nötigen Treiber zu machen. Diese sind meist als Kernelmodul vorhanden und werden bei modernen Distributionen automatisch aktiviert, wenn ein Gerät erkannt wird.

Die einzelnen Schnittstellen spreche ich über die betreffenden Dateien im Verzeichnis /dev/ an. Die erste serielle Schnittstelle ist /dev/ttyS0, der erste USB-Seriell-Wandler /dev/ttyUSB0. Bei allen weiteren wird jeweils die Zahl am Ende hochgezählt.

Bei USB-Seriell-Wandlern habe ich mitunter das Problem, dass beim Neustart des Gerätes am Wandler der Gerätetreiber zurückgesetzt wird und vom Kernel einen anderen Namen, zum Beispiel ttyUSB1 bekommt. Das ist insbesondere dann ärgerlich, wenn ich gerade mit einem Terminalprogramm an der Schnittstelle mit dem alten Namen arbeite. Hier kann ich mir mit einer Udev-Regel behelfen.

Udev-Regel

Weiss ich genau, dass ich immer nur einen USB-Seriell-Wandler verwenden werde, kann ich mir einen Link zur eigentlichen Gerätedatei anlegen lassen. Dazu lege ich eine Datei im Verzeichnis /etc/udev/rules.d/ (zum Beispiel mit Namen usb-serial.rules) mit folgendem Inhalt an:

SUBSYSTEMS=="usb-serial", SYMLINK+="usb-serial"

Anschließend kann ich den USB-Seriell-Wandler unter dem Namen /dev/usb-serial verwenden, sobald er angesteckt ist. Das ist so erstmal zusätzlicher Aufwand, um die serielle Schnittstelle zu verwenden. Wird aber der Treiber zurückgesetzt und neu initialisiert, so dass der Kernel den Namen /dev/ttyUSB1 statt /dev/ttyUSB0 vergibt, dann zeigt anschließend /dev/usb-serial darauf und ich muss mir keine Gedanken machen, welchen Schnittstellennamen ich im Terminalprogramm verwende.

Programme

Damit kommen wir schon zum nächsten Thema: Um zu sehen, was auf der seriellen Schnittstelle passiert, benötige ich ein Programm, dass meine Eingaben zur seriellen Schnittstelle und die Daten der Schnittstelle auf meinen Bildschirm schickt, ein Terminalprogramm. Dafür gibt es eine reichhaltige Auswahl, von denen ich einige Programme kurz vorstellen will.

Putty

Das Programm ist dem einen oder anderen vielleicht von MS-Windows bekannt. Dort ist es auch für mich das Mittel der Wahl für SSH- oder Telnet-Sitzungen. Doch Putty kann mehr, ich kann es unter anderem auch als Terminal-Programm für die serielle Schnittstelle verwenden. Arbeite ich mit einer grafischen Oberfläche, ist es das Mittel der Wahl für mich.

Um mit Putty die serielle Schnittstelle anzusprechen, wähle ich in der Kategorie Session als Ziel Serial.

Serielle Schnittstelle mit Putty

Hier kann ich den Namen der Schnittstellendatei sowie die Baudrate einstellen. Sinnvollerweise speichere ich die Sitzungsdaten gleich in einem Profil ab, um beim nächsten Mal nicht alles neu einstellen zu müssen.

Benötige ich spezielle Einstellungen für die serielle Schnittstelle, kann ich diese in der Kategorie Connection/Serial konfigurieren.

Schnittstelleneinstellungen bei Putty

Hier kann ich, zusätzlich zum Namen der Schnittstellendatei und der Baudrate die Anzahl der Datenbits und der Stoppbits verändern.

Bei der Parität habe ich die Wahl zwischen keiner, gerader oder ungerader Parität.

Die Flusskontrolle kann ich ganz abschalten (None), per Software (XON/XOFF) oder, wenn ich genügend Adern im Kabel durchgeschaltet habe, mittels Hardware (RTS/CTS, siehe oben) erledigen.

Habe ich an dieser Stelle etwas geändert, gehe ich noch einmal zurück in die Kategorie Session und speichere meine Änderungen im Profil ab.

Habe ich nur eine Textkonsole oder bin ich über SSH an dem Rechner mit der seriellen Schnittstelle angemeldet, greife ich auf Programme mit Curses-Oberfläche zurück.

Screen

Eine einfache Möglichkeit, die serielle Schnittstelle zu verwenden, habe ich mit screen. Dieses Programm habe ich auf Rechnern, auf die ich mit SSH zugreife, sowieso installiert und brauche somit kein zusätzliches Programm.

Screen ist eine Art Fenstermanager für Textbildschirme. Wenn screen gestartet wird, erzeugt es ein einzelnes Text-Fenster mit einer Shell oder dem in der Kommandozeile angegebene Programm. Alle Tastatureingaben bis auf das Steuerkommando werden an die Shell beziehungsweise das angegebene Programm gesandt. Alle Ausgaben von dort zeigt screen an.

Screen arbeitet als Terminalprogramm, wenn ich statt eines Programmes den Namen einer Schnittstellendatei beim Aufruf angebe, zum Beispiel:

screen /dev/ttyS0 38400

Hier die Zahl hinter dem Namen der Schnittstellendatei die Baudrate an. Diese sollte ich immer angeben. Außerdem stehen noch folgende Optionen zur Verfügung, die ich - mit Kommas getrennt - direkt folgen lasse:

Ein Aufruf mit allen Optionen könnte etwa so aussehen.

screen /dev/ttyS0 38400,cs8,-ixon,-ixoff,-istrip

In den meisten Fällen wird die Angabe der Baudrate ausreichen. Im Zweifelsfall schaue ich in der Handbuchseite von screen nach.

Busybox microcom

Auf kleinen Routern oder Geräten mit einer beschränkten Auswahl an Software ist oft Busybox installiert, so dass mir vielleicht microcom zur Verfügung steht.

Busybox ist ein sogenanntes Multi-Call-Binary, das heißt ein Programm, das die Funktionen verschiedener Programme ausführen kann. Welche Funktionen das konkrete Programm busybox auf meinem Rechner kann, bekomme ich heraus, wenn ich es ohne Argumente aufrufe:

$ busybox
...
Usage: busybox [function [arguments]...]
   or: function [arguments]...
...
Currently defined functions:
...
        md5sum, mdev, microcom, mkdir, mkfifo, mknod, mkswap, mktemp, modinfo,
...

Welche Funktion es ausführen soll, ermittelt es entweder aus dem Aufrufnamen oder dem ersten Kommandozeilenargument. Für den einfachen Aufruf der Funktionen werden daher oft Links mit anderen Namen auf das Programm busybox angelegt. Finde ich microcom in der Liste der aktuell definierten Funktionen, kann ich es verwenden. Ein Aufruf ohne weitere Argumente liefert mir die möglichen Optionen:

$ busybox microcom
...
Usage: microcom [-d DELAY] [-t TIMEOUT] [-s SPEED] [-X] TTY

Mit Option -d kann ich eine Verzögerung (in Millisekunden) zwischen den einzelnen gesendeten Bytes einstellen.

Mit Option -t kann ich einen Timeout (in Millisekunden) vorgeben, nachdem das Programm sich beendet, wenn in der angegebenen Zeit nichts gesendet oder empfangen wurde.

Mit Option -s setze ich die Baudrate.

Die Option -X deaktiviert die besondere Bedeutung von NUL und CTRL-X von der Standardeingabe.

Das sind die drei Programme, die ich am häufigsten an der seriellen Schnittstelle einsetze. Neben diesen gibt es noch etliche andere, wie C-Kermit oder Minicom, die spezielle Befehle zur Modemsteuerung kennen, so dass ich mich über Modem und Telefonleitung mit sogenannten Einwahlrechnern verbinden konnte. Diese Programme erlauben teilweise auch den Dateitransfer über die serielle Leitung während einer interaktiven Terminalsitzung. Das habe ich allerdings schon viele Jahre nicht mehr benötigt.

Posted 2017-11-07
Tags: