wake-up-neo.com

Wie stelle ich eine benutzerdefinierte Baudrate unter Linux ein?

Ich möchte über meine serielle Schnittstelle unter Linux mit einem Gerät kommunizieren, dessen Nicht-Standard-Baudrate nicht in termios.h Definiert ist.

Ich habe die "Baud Rate Aliasing" -Methode von dieser Beitrag ausprobiert, aber wenn ich mein C-Programm ausführe (ich habe es "Testprogramm" genannt), sagt Linux "testprogram sets custom speed on ttyS0. This is deprecated."

Ich habe einige Suchanfragen bei Google durchgeführt, und es scheint, dass es eine andere (neuere?) Methode gibt, um die Baudrate in einen Nicht-Standardwert zu ändern: On http://sourceware.org/ml/libc-help) /2009-06/msg00016.html Der Autor sagt, dass der c_flag Von struct termios Mit BOTHER (=CBAUDEX | B0) ODER verknüpft werden muss. Bei dieser Methode werden die Baudraten direkt in den c_ispeed Und c_ospeed - Elementen des struct termios Eingestellt. Ich weiß jedoch nicht, wie ich diese Methode in meinem C-Programm verwende. Wie der Autor sagte, ist kein BOTHER definiert/verfügbar, wenn ich termios.h Einbinde. Was sollte also getan werden, um die Baudrate auf diese Weise einzustellen?

Wie kann ich die Baudrate auf einen Nicht-Standardwert einstellen, ohne den Kernel zu ändern?

34
Felix

Mir ist das Gleiche aufgefallen, als BOTHER nicht definiert wurde. Wie Jamey Sharp sagte, können Sie es in <asm/termios.h> Finden. Nur eine Warnung, ich glaube, ich hatte Probleme, einschließlich der regulären <termios.h> - Datei zur gleichen Zeit.

Abgesehen davon habe ich festgestellt, dass es mit der Glibc, die ich habe, immer noch nicht funktioniert hat, da das Tcsetattr von Glibc das Ioctl für die alte Version von Struct Termios ausführte, die die Geschwindigkeitseinstellung nicht beachtet. Ich konnte eine benutzerdefinierte Geschwindigkeit einstellen, indem ich manuell ein ioctl mit dem neuen Stil termios2 struct durchführte, der auch verfügbar sein sollte, indem ich <asm/termios.h> Einfügte:

struct termios2 tio;

ioctl(fd, TCGETS2, &tio);
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
tio.c_ispeed = 12345;
tio.c_ospeed = 12345;
ioctl(fd, TCSETS2, &tio);
22
dougg3

Sie können eine benutzerdefinierte Baudrate mit dem Befehl stty unter Linux festlegen. Verwenden Sie beispielsweise den folgenden Befehl, um eine benutzerdefinierte Baudrate von 567890 an Ihrem seriellen Port/dev/ttyX0 festzulegen:

stty -F /dev/ttyX0 567890
17
manav m-n

dougg3 hat das so ziemlich (da kann ich nichts dazu sagen). Die wichtigste zusätzliche Sache, die Sie wissen müssen, sind die Header, die nicht miteinander in Konflikt stehen, aber die richtigen Prototypen liefern. Die Antwort ist

#include <stropts.h>
#include <asm/termios.h>

Danach können Sie den Code von dougg3 verwenden, vorzugsweise mit Fehlerprüfung bei den Aufrufen von ioctl (). Sie müssen dies wahrscheinlich in eine separate .c-Datei für den Rest Ihres seriellen Anschlusscodes einfügen, in der die normalen Begriffe zum Festlegen anderer Parameter verwendet werden. Wenn Sie zuerst POSIX-Manipulationen ausführen und dann die benutzerdefinierte Geschwindigkeit einstellen, funktioniert dies auch mit dem integrierten UART des Raspberry Pi, um eine Baudrate von 250 KB zu erhalten.

3

Für Mac-Benutzer (möglicherweise auch für einige Linux-Distributionen )

stty ospeed 999999

stty ispeed 999999
0
varatis

BOTHER scheint verfügbar zu sein von <asm/termios.h> unter Linux. Das Abrufen der Definition von dort wird nicht portierbar sein, aber ich gehe davon aus, dass diese API ohnehin nicht portierbar ist, sodass es wahrscheinlich keinen großen Verlust gibt.

0
Jamey Sharp

Auf der CPU Ihres Motherboards befindet sich ein serieller E/A-Chip ( 16650 UART ). Dieser Chip verwendet einen 8-Bit-Port als Steuer- und Datenbus, und daher können Sie ihm einen Befehl erteilen, indem Sie über den Steuer- und Datenbus auf diesen Chip schreiben.

Normalerweise hat eine Anwendung die folgenden Schritte an der seriellen Schnittstelle ausgeführt

  1. Stellen Sie Baudrate, Parität, Codierung, Flusskontrolle und Start-/Endsequenzlänge während des Programmstarts ein. Diese Einrichtung kann über ioctl an das serielle Gerät oder den Befehl 'stty' erfolgen. Tatsächlich verwendet der Befehl stty ioctl für dieses serielle Gerät.
  2. Schreiben Sie Datenzeichen auf das serielle Gerät, und der Treiber schreibt Datenzeichen über seinen 8-Bit-Datenbus auf den UART Chip.

Kurz gesagt, Sie können die Baudrate nur im Befehl STTY angeben, und dann werden alle anderen Optionen als Standard beibehalten. Sie sollten ausreichen, um eine Verbindung zu anderen Geräten herzustellen.

0
Houcheng