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
Hallo Wie erkennst DU denn, wann das Frame beendet ist? Das kannst du dann in dein Programm übertragen. Gruß Joachim
...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.
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
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...
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
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?
edit: es kann ja sein, dass ich mit der bearbeitung schneller bin, als der Frame komplett empfangen wurde?!
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.