Forum: Mikrocontroller und Digitale Elektronik String Operationen,ISR, brauche ich ein multibuffer?


von Spice (Gast)


Lesenswert?

Hallo Zusammen,

ich habe folgendes Problem, ich lese über die UART Interruptgesteuert 
Zeichen ein. Nun bekomme ich Daten in einer Frame, die auch eine 
variable Anzahl von Carriage Returns und Line Feeds beinhalten, wobei 
die Länge des Frames auch nicht bekannt ist. Wie erkenne ich in der 
Interruptroutine, dass mein Frame komplett ist? Ich habe leider keinen 
Einfluss auf die Daten die gesendet werden. Teilweise ist ein Fame 
komplett, wenn ein Carriage Return gesendet wird und teilweise wieder 
nicht. Wie löst man das am "elegantesten"? Wie funktioniert sowas, wenn 
ich z.B. 2-3 Buffer habe und bei jedem CRLF der nächste buffer aktiviert 
wird und in der ISR befüllt wird? Wie erkenne ich welchen Buffer ich in 
Main() abarbeiten muss? Über einen kleinen Denkanstoß wäre ich sehr 
dankbar...

Schönen Gruß
Spice

von XXX (Gast)


Lesenswert?

Hallo

Wie erkennst DU denn, wann das Frame beendet ist?
Das kannst du dann in dein Programm übertragen.

Gruß
Joachim

von Spice (Gast)


Lesenswert?

...ich gehe davon aus, dass wenn ich ein CRLF bekomme, dass der Frame 
auch zu Ende bzw. komplett ist. Nach dem bearbeiten des ersten buffers 
wird erst entschieden, ob der nächste gepufferte String zum aktuellen 
Frame gehört(e), oder aber eine neue Frame ist. Daher müsste ich 
eigentlich mehrere Buffer benutzen, weiss aber nicht genau, wie das in C 
am elegantesten gelöst wird.

von Peter D. (peda)


Lesenswert?

Spice schrieb:
> Über einen kleinen Denkanstoß wäre ich sehr
> dankbar...

Für die Übertragung muß es ein Protokoll geben und dieses mußt Du 
implementieren.


Spice schrieb:
> ...ich gehe davon aus, dass wenn ich ein CRLF bekomme, dass der Frame
> auch zu Ende bzw. komplett ist.

Das ist ein ganz blöder Ansatz.
Bei einem Gespräch von Mensch zu Mensch darfst Du vermuten.
Aber bei einer Datenübertragung nicht, da mußt Du wissen.

Der Sender muß sich an ein Protokoll halten und der Empfänger muß dieses 
Protokoll kennen.


Peter

von Spice (Gast)


Lesenswert?

Protokoll ist eigentlich soweit bekannt, ich bekomme kommagetrennte 
Daten, variable anzahl, teilweise ist ein CRLF ist, dann ist ein 
Datensatz zu ende und Teilweise ist ein Datensatz erst beim 2ten oder 
3ten CRLF zu ende und kann bearbeitet werden.
Ob ein Datensatz zu ende ist, weiss ich erst genau, wenn ich zumindest 
die ersten 4Bytes vor dem ersten CRLF auswerte.
Kann man das in der ISR ohne Probleme machen, wenn die Daten mit 
115200Baud reinpurzeln? Quasi nach dem ersten CRLF die ersten 4 Byte 
vergleichen, wenn identisch Frame zu ende, wenn nicht weiterlesen?
Danke für die Anregungen...

von Peter D. (peda)


Lesenswert?

Spice schrieb:
> Protokoll ist eigentlich soweit bekannt

"eigentlich" klingt ja nicht schön.

Du kannst einen FIFO im Interrupt einrichten, wo alles erstmal 
gespeichert wird. Und dabei ein Flag setzen, wenn der FIFO ein CRLF 
enthält. Ich würd das CRLF dann gleich durch '\0' ersetzen.
Im Main wird dann dieses Flag geprüft und eine komplette Zeile abgeholt 
und geparst.


Peter

von Spice (Gast)


Lesenswert?

Vielen Dank Peter,

>Im Main wird dann dieses Flag geprüft und eine komplette Zeile abgeholt
>und geparst.

was genau meinst du mit komplette Zeile? Wenn der Flag in der ISR 
gesetzt wird, dass ein CRLF erkannt wurde, werte ich dann den Teil bis 
zum ersten CRLF aus, oder nehme ich dann den kompletten buffer?

von Spice (Gast)


Lesenswert?

edit:
es kann ja sein, dass ich mit der bearbeitung schneller bin, als der 
Frame komplett empfangen wurde?!

von Peter D. (peda)


Lesenswert?

Spice schrieb:
> es kann ja sein, dass ich mit der bearbeitung schneller bin, als der
> Frame komplett empfangen wurde?!

Dann mußt Du eben warten. Das Protokoll taugt also nichts.

Das Protokoll sollte so entwickelt werden, daß es der Empfpänger so 
einfach wie möglich auswerten kann.
Z.B. es gibt eine eindeutige Zeichenkombination, die immer das 
Frameende kennzeichnet.
Sowas wie, CRLF könnte es sein, muß aber nicht, ist Mist.

Sinnvoll ist auch eine Kombination für den Framebeginn und ne CRC am 
Ende, damit unvollständige oder fehlerhafte Übertragungen erkannt werden 
können. Bei Drahtlos ist es quasi Pflicht.


Peter

von Andreas H. (andreas_h16)


Lesenswert?

Wenn man nicht gleich das Protokoll verbessern kann (wie oben 
geschildert), würde ich das so ähnlich wie bei der lexikalischen Analyse 
machen. Die ISR schreibt den Stream in einen (hier: Ring-) Puffer. Punkt 
- Mehr nicht.

In einem Zustandsautomat (FSM) einer (Main-)Schleife nehme ich Zeichen 
für Zeichen (FIFO) aus dem Puffer (START), bis ein Kriterium für 
Zeilenende erreicht ist und springe in den nächsten Zustand um die 
Bedingung zu prüfen (CHECK). Wenn die Bedingung sicher zutrifft, dann 
kann der String weiter verarbeitet werden (ACT). Wenn nicht, gehts 
wieder nach START.

Falls notwendig, kann man zu viel gelesene Zeichen (z.B. prefetch 
während CHECK) wieder in den Stream zurücklegen.

Diese Methode funktioniert in jedem Scanner/Tokenizer (lex/flex) auch so 
und die FSM kann durch weitere (Sub-)Zustände schon zum Erkennen der 
Terminalsymbole (token) verwendet werden.

Falls notwendig wird dann ein Parser zur weiteren Verarbeitung einer 
kompletten "Zeile" nachgeschaltet.

MfG,
Andreas

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.