mikrocontroller.net

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


Autor: Spice (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: XXX (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

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

Gruß
Joachim

Autor: Spice (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Spice (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Spice (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Spice (Gast)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas H. (andreas_h16)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.