Forum: Mikrocontroller und Digitale Elektronik Raspberry Pi4: UART mit Parity - Frage


von RPi4_R (Gast)


Lesenswert?

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.

von Bauform B. (bauformb)


Lesenswert?

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.

von Hmmm (Gast)


Lesenswert?

RPi4_R schrieb:
> Meine Frage ist aber jetzt, wie erkenne ich eigentlich Parity Fehler
> überhaupt?

Siehe termios(3), insbesondere das Flag PARMRK.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

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

von RPi4_R (Gast)


Lesenswert?

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 ?

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

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

von RPi4_R (Gast)


Lesenswert?

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.

von Bauform B. (bauformb)


Lesenswert?

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
Noch kein Account? Hier anmelden.