Raspberry Pi4: UART mit Parity - Frage

Gast #6904555
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.
#6904583
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.
Moderator (Firma: Titel) Persönliche Seite #6904598
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...
Persönliche Seite #6904601
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
Gast #6905472
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 ?
Persönliche Seite #6905484
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
Gast #6905544
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.
#6905783
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren