Hey!
Ich habe hier ein kleines Eval-Board mit dem XC888 Controller drauf.
Meine Frage ist folgende:
Wenn ich ein Zeichen auf dem UART Empfange liegt es ja im Register SBUF
bereit.
Was passiert nun wenn ich diesen noch nicht ausgelesen und ein neues
Zeichen wird geschickt? Wird dieses dann einfach überschrieben? Da ich
nach dem Empfang eines Zeichens noch ein bisschen was "machen" muss, ist
mein Code unter Umständen noch nicht in der Lage dass nächste Zeichen
auszulesen. Muss ich diese dann in einem Buffer zwischenspeichern oder
was wäre ein Technik den Verlust von Daten da zu minimieren?
Viele Grüße
Flipp
Flipp schrieb:> Wird dieses dann einfach überschrieben?
Du hast 10 Bitzeiten Zeit, es abzuholen. Mit dem Stopbit des nächsten
Bytes ist es weg.
Hast Du zu langsame Interrupts, mußt Du dem UART-Interrupt eine höhere
Priorität geben.
Der UART-Interrupt schreibt nur die Bytes in einen FIFO, so daß man sie
später in Ruhe auswerten kann.
Eine direkte Auswertung im Interrupt macht man üblicher Weise nicht.
Hey,
vielen Dank für deine Antwort :)
Peter Dannegger schrieb:> Der UART-Interrupt schreibt nur die Bytes in einen FIFO, so daß man sie> später in Ruhe auswerten kann.
Ok, das heisst also in meiner Interrupt Routine von dem UART mache ich
nichts anderes als die Empfangenen Daten in einen FIFO Speicher zu
schreiben -> Dieser Speicher ist ein Buffer den ich mir selber anlege
schätze ich mal...? (Sorry wenn ich so blöd nachfrage).
Das abarbeiten dieses Speichers übernehme ich dann im "normalen"
PRogramm?
Flipp schrieb:> Dieser Speicher ist ein Buffer den ich mir selber anlege> schätze ich mal...?
Das ist empfehlenswert - im UART ist meistens auch ein FIFO drin, aber
von unterschiedlicher Länge, z.B. 16 Byte. Wenn du dir selbst eines
anlegst, kannst du eine beliebige Länge wählen, und es muss auch kein
FIFO sein, man kann je nach Protokoll auch einen (oder mehrere)
Framebuffer verwenden: ich habe z.B. 256 Byte, weil eine Message maximal
250 Byte hat und mit CR abgeschlossen wird - m.a.W. der Buffer wird
einfach von Anfang an vollgeschrieben bis zum CR und dann (kopiert und)
ausgewertet.
Trotzdem kannst du das Hardware-FIFO aktiviert lassen, das macht das
Zeitverhalten robuster und ist ansonsten völlig transparent.
Gruss Reinhard
Hey,
ok ich muss jetzt leider nochmal mit einer blöden Frage fortsetzen -->
Gibt es auf dem XC888 überhaupt einen Hardware FIFO? Ich habe gerade mal
das Datenblatt durchsucht und konnte dort nichts dergleichen finden. Im
Endeffekt bleibt mir ja nichts anderes als einen eigenen in Software zu
schreiben? Oder übersehe ich da irgendwas wichtiges gerade?
Viele Grüße
Flipp schrieb:> FIFO
Das Ganze hängt auch vom "Protokoll" ab, wie die Kommunikation abläuft.
Wenn Du z.B. ein eindeutiges Startzeichen (z.B. ASCII "Stx") und eine
begrenzte Nachrichtenlänge hast, ist es besser, in der ISR nach den
Startzeichen zu suchen und anschließend die Daten in einem Array
abzulegen. Auch Prüfung der Checksum (falls vorhanden) ist in der ISR
sinnvoll.
In dem Fall ist in der ISR eine State-Machine praktisch, die mit einem
Flag dem Hauptprogramm mitteilt, wenn ein bezüglich des Formates
geprüfter und vollständiger Datensatz vorliegt. Das Hauptprogramm kann
dann der Inhalt auswerten und entsprechend reagieren.
Gruß Dietrich
Ja, das klingt gut, sowas in der Art habe ich mir auch gedacht - Die
Nachrichtenlänge kann zwischen 2 und 6 Byte variieren. Aber selbst wenn
ich meiner Hauptroutine erst die Nachricht übergeb wenn dies vollständig
angekommen ist, muss ich ja davon ausgehen dass über den UART weiter
Nachrichten übertragen werden. Sollte nun mein Hauptprogramm mit der
Verarbeitung der Daten nicht nachkommen, so muss ich die vom UART
Empfangenen Daten ja irgendwo zwischenspeichern. --> Also komme ich ja
um einen Buffer bzw. FIFO Speicher wohl nicht herum...?
Flipp schrieb:> Sollte nun mein Hauptprogramm mit der> Verarbeitung der Daten nicht nachkommen, so muss ich die vom UART> Empfangenen Daten ja irgendwo zwischenspeichern.
Wenn das nur kurzfristig ist, geht das. Aber wenn Du im Mittel oder über
einen gewissen Zeitraum mehr Daten hast als Du verarbeiten kannst, ist
was am Konzept faul...
Hast Du kein "richtiges" Protokoll? So was mit Frage-Antwort? Das wäre
natürlich viel besser: Der nächste Datensatz wird erst geschickt, wenn
Du den alten verarbeitet und quittiert hast. Dann würden auch
Übertragungsfehler erkannt: kein richtiger Datensatz -> keine Quittung.
Der Sender hat dann ein Time-Out beim Warten auf die Quittung und
wiederholt die Daten.
Wie sinnvolle welcher Aufwand ist, hängt natürlich auch davon ab, wie
wichtig die Daten sind, ob Übertragungsfehler erkannt werden sollen und
ob auch mal was verloren gehen darf. Da haben sich schon viele Leute
viele Gedanken gemacht - trivial ist das bei hohen
Sicherheitsanforderungen bestimmt nicht.
Gruß Dietrich
Hey,
ja also es gibt quasi ein kleines Protokoll. Es ist allerdings so -->
Ich Empfange eine Nachricht, interpretiere die Daten und schicke dann
z.B. einen Datensatz über den CAN Controller des µCs raus. Aber selbst
wenn ich jetzt am Ende jeder (über den UART ankommenden) Nachrichten
eine Bestätigung schicke, heisst das ja noch nicht das der
Mikrocontroller beim Eintreffen der nächsten Nachricht schon wieder 100%
da ist (vll. wurstelt er noch was an der CAN Nachricht rum).
Oder habe ich deine Antwort so zu verstehen, dass ich mein System so
auslegen muss, dass derjenige der über den UART schickt irgendwie
begrenzt werden muss, so dass er nie "zuviele" Nachrichten schickt ,dass
quasi mein Buffer überlaufen würde?
Flipp schrieb:> ja also es gibt quasi ein kleines Protokoll. Es ist allerdings so -->> Ich Empfange eine Nachricht, interpretiere die Daten und schicke dann> z.B. einen Datensatz über den CAN Controller des µCs raus. Aber selbst> wenn ich jetzt am Ende jeder (über den UART ankommenden) Nachrichten> eine Bestätigung schicke, heisst das ja noch nicht das der> Mikrocontroller beim Eintreffen der nächsten Nachricht schon wieder 100%> da ist (vll. wurstelt er noch was an der CAN Nachricht rum).
Aber wenn Du die Betätigung schickst, kann die ISR ja schon den nächsten
Datensatz empfangen, während Du am CAN rummachst. Du bearbeitest die
neue Nachricht dann halt erst, wenn der CAN fertig ist. Solange bekommt
der Sender noch keine Bestätigung und wartet (die max. Wartezeit muss
natürlich
dazu passen).
> Oder habe ich deine Antwort so zu verstehen, dass ich mein System so> auslegen muss, dass derjenige der über den UART schickt irgendwie> begrenzt werden muss, so dass er nie "zuviele" Nachrichten schickt ,dass> quasi mein Buffer überlaufen würde?
Das gilt natürlich immer: wenn Du mehr bekommst als Du verarbeiten
kannst, läuft irgendwann jeder Puffer über - oder Du wirfst die Daten
gleich weg und hast Datenverlust.
Hast Du aber eine Quittung im System, kann das nicht passieren.
Gruß Dietrich
Flipp schrieb:> dass derjenige der über den UART schickt irgendwie> begrenzt werden muss
Logisch denken: es gibt nur 2 Möglichkeiten:
1. per Handshake bzw. Protokoll dafür sorgen, dass nur soviele
Nachrichten verschickt werden, wie verarbeitet werden können.
2. Das System so planen, dass es egal ist, wenn Nachrichten
verlorengehen. In den meisten Fällen ist das keine gute Idee. Aber bei
Regelungen z.B. kann das funktionieren - wenn ein geänderter Sollwert
nicht ankommt, dann kommt er eben mit der nächsten Nachricht.
(es gibt natürliche eine dritte Möglichkeit: das System funktioniert
einfach nicht).
Es ist aber so gut wie nie sinnvoll, den Empfänger auf Dauer zu
überfahren.
Gruss Reinhard
Hey,
vielen Dank für die Antworten!!
Also ich denke ich werde es so machen, dass ich dem Sender am UART
mitteile wenn ich wieder soweit bin Daten zu Empfangen. Ich denke das
ist die unkomplizierteste und sicherste Lösung welche auch für meine
Zwecke völlig ausreichend ist.
Ich danke euch nochmal für die schnelle und freundliche Hilfe!!!
Viele Grüße
Flipp