Hallo, ich betreibe einen RPi4 und bin estmals beim Erstellen eines Programms in C das serielle Daten von Sensoren abholt die mit 8E1 arbeiten. Soweit funktioniert schon alles, d.h. ich kann Daten senden und empfangen mit Parity Even. Meine Frage ist aber jetzt, wie erkenne ich eigentlich Parity Fehler überhaupt? Dazu gibt es sehr wenig im WEB zu finden. Kann mann den Returnwert von ... = read(fd,...) dazu verwenden? Z.B. wenn -1 ist hat es Parityfehler gegeben? Wäre für sachdienliche Hinweise sehr dankbar.
Anscheinend mögen die Leute nicht, wenn read() -1 liefert. man termios sagt:
1 | PARMRK |
2 | If this bit is set, input bytes with parity or framing errors are |
3 | marked when passed to the program. This bit is meaningful only |
4 | when INPCK is set and IGNPAR is not set. |
5 | The way erroneous bytes are marked is with two preceding bytes, |
6 | \377 and \0. Thus, the program actually reads three bytes for one |
7 | erroneous byte received from the terminal. If a valid byte has |
8 | the value \377, and ISTRIP (see below) is not set, the program |
9 | might confuse it with the prefix that marks a parity error. |
10 | Therefore, a valid byte \377 is passed to the program as two bytes, |
11 | \377 \377, in this case. |
12 | If neither IGNPAR nor PARMRK is set, read a character with |
13 | a parity error or framing error as \0. |
RPi4_R schrieb: > Meine Frage ist aber jetzt, wie erkenne ich eigentlich Parity Fehler > überhaupt? Siehe termios(3), insbesondere das Flag PARMRK.
Bauform B. schrieb: > The way erroneous bytes are marked is with two preceding bytes, > \377 and \0. Ja schlags kaputt, da ist sie wieder, die Escape-Sequenz. Und dann zum Maximieren der Obfuscation gleich noch als Oktalwert. Konnte der Schreiberling da jetzt nicht einfach 0xff hinschreiben? https://stackoverflow.com/questions/6209560/what-is-363-353-377-377-377-177 > Anscheinend mögen die Leute nicht, wenn read() -1 liefert. Wobei \377 bzw. 0xff als signed betrachtet ja auch wieder -1 wäre...
:
Bearbeitet durch Moderator
Hi evtl. hilft dir https://www.cmrr.umn.edu/~strupp/serial.html -> PARMRK Ist aber die Frage ob das auf dem Pi und dessen seriellem Treiber auch umgesetzt ist. Oder aber https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -> TIOCGICOUNT Entgegen der Beschreibung enthält serial_icounter_struct auch Fehlerzähler. struct serial_icounter_struct { int cts, dsr, rng, dcd; int rx, tx; int frame, overrun, parity, brk; int buf_overrun; int reserved[9]; }; Scheint vom RPi Treiber auch gefüllt zu werden: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/tty/serial/amba-pl011.c?h=v5.16-rc4#n336
Ich bitte um Nachsicht wenn ich jetzt mal dumm fragen muss, da ich bisher noch nie mit RPis gearbeitet habe. Bisher kenne ich das nur von MCs, wo ich direkt die Fehlerbits per Register sehen konnte. Wie komme ich denn an PARMRK ran? Muss ich dazu wenn ich -1 empfange tcgetattr(fd,.. ausführen und dann z.B. PARMRK anschauen zur Fehlerbehandlung ?
RPi4_R schrieb: > Wie komme ich denn an PARMRK ran? Muss ich dazu wenn ich -1 > empfange tcgetattr(fd,.. ausführen und dann z.B. PARMRK > anschauen zur Fehlerbehandlung ? Nein, du musst PARMRK per tcsetattr setzen. Dann wird dein Datenstrom um bestimmte Sequenzen erweitert wenn ein Parityerror auftritt:
1 | PARMRK causes parity errors to be 'marked' in the input stream using special characters. If IGNPAR is enabled, a NUL character (000 octal) is sent to your program before every character with a parity error. Otherwise, a DEL (177 octal) and NUL character is sent along with the bad character. |
Matthias
Ok, jetzt hab ich's glaube ich. Danke Matthias. Wenn PARMRK und INPCK gesetzt ist kommen für jedes fehlerhafte Byte 3 Bytes (\377 and \0 and \xxx). So verstehe ich das jetzt aus der termios structure documentation. Wenn read(fd,...) -1 liefert ist dann irgend ein anderer unbekannter Fehler aufgetreten der nichts mit Parity zu tun hat. Hoffe das ist richtig.
RPi4_R schrieb: > Wenn read(fd,...) -1 liefert ist dann irgend ein anderer unbekannter > Fehler aufgetreten der nichts mit Parity zu tun hat. So verstehe ich das auch. Ein beliebter Fehler für read() == -1 passiert, wenn jemand den USB-Stecker vom Konverter raus zieht. Den RS-232-Stecker merkt man nicht, dann geht's nur nicht. Dagegen sind eigentlich DTR und DSR erfunden worden, man könnte den Eingang mit ioctl(fd, TIOCMGET, &modem_status) abfragen. Überhaupt listet "man ioctl_tty" ein paar nützliche Funktionen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.