Forum: Mikrocontroller und Digitale Elektronik UART 8N1 und 9N1 Mischen


von Patrick S. (patrick_s81)


Lesenswert?

Hallo,

ich bin zurzeit mit dem Problem beschäftigt, dass ich mit einem ATMEGA 
an der UART Schnittstelle eines Embedded Linux hänge. Mehrere Prozesse 
können an die UART Schnittstelle Daten übertragen. Der ATMEGA muss nun 
erkennen, wann er angesprochen wird. Dazu habe ich nun zwei Überlegungen 
getroffen:

1. Ein Softwareprotokoll, welches alle ankommenden Daten scannt und 
entscheidet, welche Daten zum ATMEGA gehören. Gibt es da schon fertige 
Protokolle(XMODEM)?

2. Die UART des Linux Systems in den 9N1 Modus versetzen, sobald mein 
Prozess Daten überträgt und auf Antworten wartet. Funktioniert das 
Problemlos oder kommt es zu Problemen, wenn man zwischen dem 8N1 und 9N1 
Modus wechselt?

von (prx) A. K. (prx)


Lesenswert?

Bahnhof. 9n1 gibts in Hardware allerdings seltener als einem lieb ist, 
es sei denn man verwendet dazu 8m1/8s1 und wertet den Fehlerstatus aus.

: Bearbeitet durch User
von Patrick S. (patrick_s81)


Lesenswert?

Eine Idee hätte ich da noch, anscheinend werden keine Steuerzeichen 
übertragen. Dann könnte ich einfach ein Steuerzeichen verwenden, um mit 
dem ATMEGA zu kommunizieren.

von (prx) A. K. (prx)


Lesenswert?

Wenn in den nächsten Stunden kein intelligenter Kommentar kommt, 
solltest du vorsorglich davon ausgehen, dass auch die Anderen deine 
Problembeschreibung nicht verstanden haben.

von db8fs (Gast)


Lesenswert?

Multipunkt-zu-Punkt-Verbindung über UART? Dann wirst Du um einen 
Software-Multiplexer bzw. Serializer nicht drumrumkommen, wenn mehrere 
Kanäle vom selben TxD bedient werden sollen und darauf schreiben dürfen.
Wenn nur ein ATmega als Receiver am UART hängt, der von verschiedenen 
Prozessen befummelt wird, kannst du dir vielleicht mit Mitteln der IPC 
behelfen, z.B. Locks. Siehe hier:
http://openbook.rheinwerk-verlag.de/linux_unix_programmierung/Kap09-004.htm

Patrick S. schrieb:
> Mehrere Prozesse
> können an die UART Schnittstelle Daten übertragen. Der ATMEGA muss nun
> erkennen, wann er angesprochen wird.

Angenommen, deine UARTs unterstützen deine gewünschte 
9Bit-Konfiguration.
Wie willst du ausschließen, dass dein neuntes Bit nicht durch Grütze auf 
der Leitung für die 8-Bit-konfigurierten nicht so aussieht, wie gültige 
Datenworte?

Oder wie soll das funktionieren, nur durch Wechseln der 
UART-Datenkonfiguration? Soll jeder Prozess immer prüfen, welche 
UART-Einstellung gerade anliegen?

von Georg (Gast)


Lesenswert?

Patrick S. schrieb:
> ich bin zurzeit mit dem Problem beschäftigt, dass ich mit einem ATMEGA
> an der UART Schnittstelle eines Embedded Linux hänge.

Die serielle Schnittstelle ist eine Punkt zu Punkt-Verbindung - einfach 
Daten wild in die Gegend zu werfen nach dem Motto "to whom it may 
concern" ist ein klarer Missbrauch, mal ganz davon abgesehen, dass TxD 
nicht mehrfach belegt werden kann ohne Protokollsteuerung, wer gerade 
dran ist. Wie soll denn eine Sicherung der Übertragung funktionieren, 
wenn dazwischen alle möglichen Daten kommen, die garnicht zur aktuellen 
Übertragung gehören?

Man kann sicher auch solchen Murks irgendwie zum Funktionieren bringen, 
aber es bleibt kapitaler Murks.

Georg

von Patrick S. (patrick_s81)


Lesenswert?

db8fs schrieb:
> Oder wie soll das funktionieren, nur durch Wechseln der
> UART-Datenkonfiguration? Soll jeder Prozess immer prüfen, welche
> UART-Einstellung gerade anliegen?


Nur mein Programm würde die 9N1 Kommunikation verwenden. Sobald ein 
Paket verarbeitet wäre, würde ich die Konfiguration wieder zurücksetzen.

db8fs schrieb:
> Angenommen, deine UARTs unterstützen deine gewünschte
> 9Bit-Konfiguration.
> Wie willst du ausschließen, dass dein neuntes Bit nicht durch Grütze auf
> der Leitung für die 8-Bit-konfigurierten nicht so aussieht, wie gültige
> Datenworte?

Das ist halt die Frage, ob so etwas generell funktioniert. Ich habe 
bisher nichts vergleichbares gefunden, daher meine Frage an euch. Ob es 
da schon sichere Lösungen gibt.

von c-hater (Gast)


Lesenswert?

Patrick S. schrieb:

> Nur mein Programm würde die 9N1 Kommunikation verwenden.

Das hilft garnichts, weil viele mögliche 9N1-Datenworte auch als 8N1 
interpretiert gültig sind und umgekehrt genauso. Am Ende empfangen alle 
nur noch Grütze.

> Das ist halt die Frage, ob so etwas generell funktioniert.

Ganz sicher nicht ohne weitere Maßnahmen. Die laufen allerdings auf ein 
Protokoll hinaus. Das kann man allerdings viel leichter umsetzen, wenn 
man ein gemeinsames Frameformat verwendet, z.B. 9N1 für alle. Dann 
könnte man ganz einfach eins der 9 Bits als "Adresse" verwenden. Oder 
8N1 für alle, wobei vor den eigentlichen Daten jeweils ein Adressbyte zu 
senden ist.

Es gibt noch Tausende anderer Möglichkeiten, sowas umzusetzen. Die Frage 
ist nur: Warum sollte man sich das heute überhaupt antun, wo eine 
zusätzliche serielle Schnittstelle für'n Fünfer an jeder Ecke zu haben 
ist...

von Patrick S. (patrick_s81)


Lesenswert?

Ich habe leider nur eine Schnittstelle zur Verfügung. Daher auch meine 
Frage.

von db8fs (Gast)


Lesenswert?

Ok, da es noch nicht ganz klar zu sein scheint (falls doch, bitte den 
Post zu entschuldigen) — angenommen, deine Konfiguration sähe so aus:

AVR <--*1--> /dev/ttyS0 <--*2--> P1, P2, P3

Nehmen wir nun an, jeder der Prozesse P1, P2, P3 schreibt auf 
/dev/ttyS0, aber nur P2 gibt Steuerbefehle, die Daten von P1 und P3 
würden vom AVR über einen anderen Bus an irgendeinen weiteren Teilnehmer 
auf deiner Platine verteilt werden.

Was du tun müsstest um diesen Aufbau zu verwenden:

*2:
- für die verschiedenen Prozesse P1,P2,P3 einen zusätzlichen Prozess P4 
schaffen, der mittels IPC die Daten synchronisiert entgegennimmt und 
kontrolliert auf /dev/ttyS0 schreibt. P1,P2,P3 dürfen nicht mehr 
direkt auf die Schnittstelle zugreifen, sondern müssen per P4 
synchronisiert werden. P4 könnte auch einfache Steuerbefehle beinhalten 
zum Umschalten des internen Status des AVRs.

*1:
- zunächst Baudrate und Datenflusssteuerung auf beiden Teilnehmern 
konstant halten (8N1), nur so ist eine sichere Verbindung garantiert.
- der AVR muss auf die Steuerbefehle von P4 warten (StateMachine) und 
deserialisieren falls notwendig.

Fazit: um ein kleines Protokoll für dein System kommst du nicht drumrum.

von Bestromer (Gast)


Lesenswert?

Patrick S. schrieb:
> ... dass ich mit einem ATMEGA
> an der UART Schnittstelle eines Embedded Linux hänge. Mehrere Prozesse
> können an die UART Schnittstelle Daten übertragen.

Das sieht mir aber nach einer Punkt zu Punkt Verbindung aus....warum 
sprechen alle von Multipunkt???

von Bestromer (Gast)


Lesenswert?

...wenn Du dem Atmega etwas mitteilen willst, vereinbare einfach einen 
ein und ausführenden Tag...alles zwischen den Tags ist für den Atmega...

von Amateur (Gast)


Lesenswert?

Normalerweise kann man davon ausgehen, dass es nur eine Frage der Zeit 
ist, bis zwei gleichzeitig quasseln.

Schon allein der Gedanke das Gewirr, das dabei entsteht, auseinander zu 
dröseln, reicht für ein paar graue Haare.

Wenn Du aber auf keinen Fall davon lassen kannst, bastle Dir ein dazu 
passendes Protokoll.
Name(Adresse), Daten(Binär oder so) reicht schon.

Das Namens-Byte kann, wenn nicht 255 Adressaten benötigt werden, sogar 
Hilfsdaten, wie z.B. ein paar Prüf-Bits oder einen Schlüssel für die 
folgenden (Befehl) Daten aufnehmen.

von Patrick S. (patrick_s81)


Lesenswert?

Es kommuniziert eigentlich nur mein Programm und das Linux System 
während des Bootvorgangs(+Bootloader). Die Statusmeldungen kann ich 
wahrscheinlich im Linuxsystem abschalten.

von Bestromer (Gast)


Lesenswert?

kann mir mal bitte jemand erklären warum es sich hier um mehr als zwei 
Teilnehmer handelt???
R mich erschliesst sich hier kein Multipunkt-System???

von Patrick S. (patrick_s81)


Lesenswert?

Eine Zusammenfassung, da meine Erklärung wohl mehrdeutig interpretiert 
wird. Ich habe ein Embedded Linux System, welches nur über eine 
UART-Schnittstelle verfügt. An dieser Schnittstelle hängt ein ATMEGA. 
Während das System bootet, meldet sich über diese Schnittstelle der 
Bootloader und der Linux Kernel. Nachdem das System hochgefahren ist, 
kommt es vor, dass sich einzelne Prozesse an dieser Schnittstelle zu 
Wort melden. Meine Aufgabe ist es jetzt, zu erkennen, welche Daten an 
den ATMEGA gerichtet sind.

von Patrick S. (patrick_s81)


Lesenswert?

db8fs schrieb:

> Fazit: um ein kleines Protokoll für dein System kommst du nicht drumrum.

Gibt es denn schon ein Protokoll für solche Aufgaben?
Ich bin schon dabei ein Protokoll zu schreiben, nur ist es etwas 
aufwendig.

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


Lesenswert?

Patrick S. schrieb:
> Ich habe ein Embedded Linux System, welches nur über eine
> UART-Schnittstelle verfügt.
Und auch nur über 1 einzige solche UART-Schnittstelle insgesamt? Hört 
sich extrem autistisch an...

Patrick S. schrieb:
> 2. Die UART des Linux Systems in den 9N1 Modus versetzen, sobald mein
> Prozess Daten überträgt und auf Antworten wartet. Funktioniert das
> Problemlos oder kommt es zu Problemen, wenn man zwischen dem 8N1 und 9N1
> Modus wechselt?
Zeichne einfach mal ein paar Datenströme auf und du wirst sehen, dass 
eine Unterschiedung nicht zuverlässig möglich ist.

> Meine Aufgabe ist es jetzt, zu erkennen, welche Daten an den ATMEGA
> gerichtet sind.
Ich würde diese Debug-Ausgaben vom Kernel ausschalten, damit nur die 
gewünschten Daten ankommen. Oder die Ausgaben bestenfalls über einen 
Portpin gesteuert zulassen. Oder über ein vor der Initialisierung zu 
sendendes Kommando...

von Patrick S. (patrick_s81)


Lesenswert?

@Lothar Miller

Der Linux Kernel und Bootloader kommunizieren hauptsächlich in 
Menschenlesbarer Form, daher sollten kaum Steuerzeichen auftreten.
Meine Idee war eine Kombination von Steuerzeichen und ausschließlich 
Text als Paket zu übertragen.


Paket:
4 Byte Steuerzeichen + 6 Byte Text
0 - 255 Byte Daten in Menschenlesbarer Form
2 Byte Steuerzeichen (CR LF)

So sollte die Wahrscheinlichkeit sehr gering sein, dass der ATMEGA die 
falschen Daten erhält.

von Bestromer (Gast)


Lesenswert?

Patrick S. schrieb:
> Eine Zusammenfassung, da meine Erklärung wohl mehrdeutig
> interpretiert
> wird. Ich habe ein Embedded Linux System, welches nur über eine
> UART-Schnittstelle verfügt. An dieser Schnittstelle hängt ein ATMEGA.
> Während das System bootet, meldet sich über diese Schnittstelle der
> Bootloader und der Linux Kernel. Nachdem das System hochgefahren ist,
> kommt es vor, dass sich einzelne Prozesse an dieser Schnittstelle zu
> Wort melden. Meine Aufgabe ist es jetzt, zu erkennen, welche Daten an
> den ATMEGA gerichtet sind.

....so hab ich das auch von Anfang an verstanden, bis Einer es falsch 
interpretiert hat und alle sich einig waren das mehr als zwei Teilnehmer 
mittels RS232 kommunizieren.
Ist ja fast wie in der deutschen Medienwelt, die Bildzeitung 
veröffentlicht irgend welchen geistigen Dünnschiss und plötzlich sind 
sich alle anderen Zeitungen ungeprüft einig das es nur so sein kann.
...egal,dann wäre ja die Sache mit der Kennzeichnung als 
ein-/ausführenden Tag prima....z.B. #*/ alles was jetzt kommt ist für 
den Atmega /*# alles was jetzt kommt ist nicht mehr für den Atmega....
Du musst also im Atmega nur auf diese zwei Bytekombinationen Filtern und 
alles dazwischen nach Deinem Wünschen verarbeiten.

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


Lesenswert?

Patrick S. schrieb:
> Meine Idee war eine Kombination von Steuerzeichen und ausschließlich
> Text als Paket zu übertragen.
Die Idee klappt natürlich bestenfalls so lange, wie die Übertragung für 
den AVR nicht unterbrochen werden kann...

Patrick S. schrieb:
>>> Nachdem das System hochgefahren ist, kommt es vor, dass sich einzelne
>>> Prozesse an dieser Schnittstelle zu Wort melden.
Denn was, wenn so ein Prozess höherprior ist und sich in eine laufende 
AVR-Übertragung hineindrängt?

von Malte S. (maltest)


Lesenswert?

Du hast also zwei getrennte Problemstellungen. Erstens kommt die der 
Bootprozess in die Quere, zweitens hast du anschließend mehrere 
Prozesse, die unkoordiniert auf den UART zugreifen.

Wenn du wirklich nur einen UART hast und nicht ein anderes Device für 
die Bootausgaben nehmen kannst, ist das nicht so doll. Eine Abhilfe 
wäre, erst nach erfolgtem Boot über einen GPIO dem uC mitzuteilen, dass 
ab jetzt Daten für ihn bestimmt sind. Problem ist, dass ja trotzdem 
jederzeit noch Kram vom Kernel ankommen kann. Denn wenn der seine 
Bootmeldungen dahin schreibt (was man mit quiet in der Kommandozeile 
weitgehend verhindern kann) dann ist wahrscheinlich auch /dev/console 
auf diesen UART gemappt, d.h. du wirst auch jede weitere Ausgabe des 
Kernels dahin bekommen, z.B. im Fall einer Panic.

Zweitens ist mir noch nicht ganz klar was mit deinen mehreren Prozessen 
ist. Die sollen alle mit dem AVR kommunizieren? Das ist schlecht, das 
sollte nur ein einziger Daemon tun, der diese Kommunikation sauber 
synchronisiert durchführt. Mit diesem kommunizieren dann deine anderen 
Prozesse über einen IPC-Mechanismus deiner Wahl. Es sei denn, deine 
Prozesse sind kurzlebiger Natur und du kannst auf andere Weise 
sicherstellen, dass nur einer davon zu jeder Zeit den UART benutzt, mit 
einem Synchronisations-Mechanismus deiner Wahl.

In jedem Fall sollte dein Protokoll die Möglichkeit haben, die 
Kommunikation zurückzusetzen, wenn dein Linux gewollt oder nach Panic 
etc. gebootet wurde oder der o.g. Daemon bzw. Die koordinieren 
Einzelprozesse starten, könnte ja sein, dass ihr Vorgänger vorzeitig 
beendet wurde. Dazu bietet sich wahlweise ein GPIO an (kombinierbar als 
Flag für gültige Daten, s.o.) oder ein entsprechendes Steuerzeichen bzw. 
eine Sequenz von Steuerzeichen.

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


Lesenswert?

Malte S. schrieb:
> Zweitens ist mir noch nicht ganz klar was mit deinen mehreren Prozessen
> ist. Die sollen alle mit dem AVR kommunizieren?
Nein, Es sind alles Debug-Ausgaben des Systems. Nur der neue 
"User"-Prozess hat Daten für den AVR.

Patrick S. schrieb:
> Nachdem das System hochgefahren ist, kommt es vor, dass sich einzelne
> Prozesse an dieser Schnittstelle zu Wort melden.
Patrick S. schrieb:
> Die Statusmeldungen kann ich wahrscheinlich im Linuxsystem abschalten
Gut. Mach das zuallererst.

von Malte S. (maltest)


Lesenswert?

Lothar M. schrieb:
> Nein, Es sind alles Debug-Ausgaben des Systems. Nur der neue
> "User"-Prozess hat Daten für den AVR.

Aaah. Und schreiben die explizit auf den UART oder einfach auf 
/dev/console? Es wäre sehr hilfreich, zur Kommunikation mit der 
Peripherie nicht den Konsolenport zu nehmen, das wird sonst früher oder 
später wieder zu weiteren Überraschungen führen.

von Patrick S. (patrick_s81)


Lesenswert?

Ein anderer Prozess, sollte die Kommunikation nicht stören. Solange ich 
nicht zu viele Daten übertrage. Außerdem würden dann auch Debugausgaben, 
falsch dargestellt werden, wenn ein Prozess mit höherer Priorität 
ankommt. Der UART-Buffer hat typischerweise eine Größe von 4096 Bytes.

von Malte S. (maltest)


Lesenswert?

Eine dreckige, aber möglicherweise effiziente Variante wäre, darauf zu 
setzen, dass alles, was an Text so normalerweise über die Konsole geht, 
7-bit ASCII ist. Dann könntest du in deiner Kommunikation bei jedem Byte 
das MSB setzen. Falls du eigentlich auch nur (ASCII) Textdaten hast, 
kannst du das MSB komplett als Flag verwenden, ansonsten dich an UTF-8 
orientieren o.ä.

von Patrick S. (Gast)


Lesenswert?

Malte S. schrieb:
> Eine dreckige, aber möglicherweise effiziente Variante wäre, darauf zu
> setzen, dass alles, was an Text so normalerweise über die Konsole geht,
> 7-bit ASCII ist.

Daran habe ich noch nicht gedacht. Das werde ich demnächst probieren. 
Standardmäßig läuft das Linux System mit dem UTF-8 Format. Dann werde 
ich zusätzlich mehrere Bytes einsetzen, damit mir kein anderer Prozess 
Probleme bereitet.

von Malte S. (maltest)


Lesenswert?

Patrick S. schrieb:
> Standardmäßig läuft das Linux System mit dem UTF-8 Format.

Ja, aber das betrifft selten die Ausgaben auf der Konsole, die 
normalerweise auf Englisch sein sollten. Daher sollte™ byte & 0x80 dort 
nie vorkommen. YMMV.

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.