Fehler beim Lesen von Schnittstellen

Hallo Leute,

ich habe hier ein eigenartiges Problem. Also ich habe ein Gerät, was mit mir per RS232 kommuniziert. Das Betriebssystem des Hosts ist Linux, die Gegenseite ist ein Mikrocontroller. Das funktioniert auch alles soweit. Aber ich habe folgendes Problem.

Ich sende ein 0xA8 und müsste ein Echo empfangen. Ich empfange aber nur 0x28. Mit anderen Worten: Es fehlt das erste Bit.

Folgender Code ist verantwortlich (Fehlerbehandlungen sind entfernt):

int devicehandle; 
struct termios options; 
unsigned char buffer[1];

//RS232-Kanal öffnen (lesen und Schreiben erlaubt)
 devicehandle=open(device, O\_RDWR | O\_NOCTTY | O\_NDELAY);

 fcntl(devicehandle, F\_SETFL, 0);

 //RS232 konfigurieren
 tcgetattr(devicehandle, &options);

 //setzte baudrate
 cfsetispeed(&options, B38400);
 cfsetospeed(&options, B38400);

 //Read und Local setzen
 options.c\_cflag |= (CLOCAL | CREAD);

 //gerade Parität, 1 Start&Stopbit, 8 Datenbits
 options.c\_cflag |= PARENB; /\* Enable parity \*/
 options.c\_cflag &= ~PARODD; /\* Turn odd off =\> even \*/
 options.c\_cflag &= ~CSTOPB; /\* Set 1 Stopbit \*/
 options.c\_cflag &= ~CSIZE; /\* Mask the character size bits \*/
 options.c\_cflag |= CS8; /\* Select 8 data bits \*/

 //Disable hardware flowcontrol
 options.c\_cflag &= ~CRTSCTS;

 //Raw Data Ausgabe
 options.c\_oflag &= ~OPOST;
 options.c\_oflag |= ONLCR;

 //Raw data Einlesen mit Parity-check
 options.c\_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
 options.c\_iflag |= (INPCK | ISTRIP);

 //Set timeout to 1s
 options.c\_cc[VMIN] = 0;
 options.c\_cc[VTIME] = 10;

 //Software flowcontrol ausschalten
 options.c\_iflag &= ~(IXON | IXOFF | IXANY);

 //Neue Einstellungen sofort auf Port übertagen
 tcsetattr(devicehandle, TCSAFLUSH, &options);

 //Puffer leeren
 tcflush(devicehandle, TCIFLUSH);

//Hier geht das senden und empfangen los.

buffer[0]=0xA8;

printf("Sende %02X\n", buffer[0]); //reelle Ausgabe ist hier: A8

write(devicehandle, buffer, 1);

tcdrain(devicehandle); //warten, bis alles gesendet.

read(devicehandle, buffer, 1);

printf("Empfange %02X\n", buffer[0]); //Ausgabe sollte sein A8, ist aber 28

close(devicehandle);

Sieht für mich irgendwie normal aus. Das Oszi-Bild ist auf Sende- und Empfangsseite identisch. Ich gehe also davon aus, dass er tatsächlich ein richtiges Echo schickt.

Ich versteh die Welt nicht mehr.

Günther

Hallo Leute,

ich habe hier ein eigenartiges Problem. Also ich habe ein
Gerät, was mit mir per RS232 kommuniziert. Das Betriebssystem
des Hosts ist Linux, die Gegenseite ist ein Mikrocontroller.
Das funktioniert auch alles soweit. Aber ich habe folgendes
Problem.

Ich sende ein 0xA8 und müsste ein Echo empfangen. Ich empfange
aber nur 0x28. Mit anderen Worten: Es fehlt das erste Bit.

Sieht für mich irgendwie normal aus. Das Oszi-Bild ist auf
Sende- und Empfangsseite identisch. Ich gehe also davon aus,
dass er tatsächlich ein richtiges Echo schickt.

Ich versteh die Welt nicht mehr.

Günther

Hallo Günther,

traditionell hat Unix Schwierigkeiten mit 8bit-Codes, aber das sollte inzwischen überwunden sein, es gibt ja sogar deutsche Tastaturen!

  1. Senden/Empfang identisch mag ja sein, aber auch richtig? Entweder du zählst die Bits ab oder du nimmst gleich einen Protokoll-Analysator oder du hängst wenigstens einen PC mit Hyperterminal dran.

  2. Hast du überhaupt schon einmal ASCII > 127 erfolgreich übertragen?

  3. Warum probierst du nicht überhaupt zuerst mal mit einem Terminalprogramm, die gibt es doch auch unter Unix zu hunderten?

Gruss Reinhard

Hallo Reinhard,

options.c\_iflag |= (INPCK | ISTRIP);

was the enemy,

options.c\_iflag &= ~(ISTRIP);

was my hero.

Bei dem Ding widersprechen sich die Informationsquellen. Laut http://www.easysw.com/~mike/serial/serial.html#2_5 löscht das das Parity-Bit, laut http://man.cx/stty(1)/de wird das 8.Datenbit gelöscht, was wohl auch stimmt.

Danke trotzdem für deine Hilfe. Ich habe jetzt den ganzen Vormittag damit verbracht, mich mit einer Drahtbrücke zu unterhalten. War nicht sonderlich abwechslungsreich und Unsinn hat das Ding auch die ganze Zeit geredet.

Aber jetzt sind wir wieder Freunde.

Günther

Hallo Günther,

das meinte ich mit traditionellen 8bit-Problemen. Viele Unix-Programmierer haben niemals damit gerechnet, dass es ein Leben ausserhalb des 7bit-USASCII geben könnte. Wir hatten Sun-Workstations für 200 kDM, bei denen die Software einfach abgestürzt ist, wenn in einem Text äöü vorkam, und es kann dir heute noch passieren, dass ein Unix-Mailserver aus deiner Mail alles fremdländische rausschmeisst.

Daher gibt es dieses Strippen des MSB überhaupt, mit der RS232C-Schnittstelle hat das so gut wie nichts zu tun. Die Programmierer konnten sich wohl auch nicht vorstellen, dass es jemals 8bit PLUS Parity geben könnte, daher die unterschiedliche Dokumentation.

Gruss Reinhard

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

1 Like

Daher gibt es dieses Strippen des MSB überhaupt, mit der
RS232C-Schnittstelle hat das so gut wie nichts zu tun. Die
Programmierer konnten sich wohl auch nicht vorstellen, dass es
jemals 8bit PLUS Parity geben könnte, daher die
unterschiedliche Dokumentation.

Alles klar. Unter dem Gesichtspunkt macht es freilich Sinn. Wenn erweitertes ASCII zum Absturz führen könnte, dann sollte man das von vornherein verbieten können. Wieder was gelernt.

Danke und Sternchen.

Günther

Hallo Günther,

Bei dem Ding widersprechen sich die Informationsquellen. Laut
http://www.easysw.com/~mike/serial/serial.html#2_5 löscht das
das Parity-Bit,

Das ist ein 7-Bit Ami.

laut http://man.cx/stty(1)/de wird das
8.Datenbit gelöscht, was wohl auch stimmt.

Das ist die exakte Beschreibung, was das Flag bewirkt.

Die Problematik ist eigentlich noch etwas komplexer als sie schon beschrieben wurde !

Eigentlich wird das Parity-Bit normalerweise vom UART ausgewertet. Bei 7-Bit Daten + Parity, muss dazu aber das UART entsprechend initialisiert werden.
Bei 7Bit + Parity Übertragung, kann man das UART aber auch auf 8Bit, No Parity initialisieren, dann wird das Parity-Bit „sichtbar“ und man muss es mit ISTRIP entfernen.

Ich habe eigentlich nie begriffen wieso ich das Parity selber auswerten soll, wenn das vor 30 Jahren schon ein durchschnittliches UART konnte ?!

MfG Peter(TOO)