Hallo Forum, ich hab da ein kleines Problem mit meinem FIFO-Buffer. Bereits gestern konnte ich ein Teil des Problems mit eurer Hilfe lösen. Folgendes: Mit Hilfe der UART Lib von Peter Fleury will ichserielle Daten empfangen und sofort wieder versenden. Mein Code hab ich zunächst in eine Datei (new2) geschrieben und es funktioniert. Da die Übertragung meiner seriellen Daten (Gerät --> uC) länger dauert, als die Zeitspanne, in denen mein uC den FIFO leert, werden dazwischen 0x00 gesendet. Diese filtere ich raus, sodass ich am Hyperterminal nur meine vom Gerät gesendeten Strings sehe. Das funktioniert soweit. Nun wollte ich aber die UART Initialisierung in eine separate Datei ablegen (new10), sodass ich sie auch in andere Projekte einbinden kann. Allerdings klappt das noch nicht so ganz. Nun ist es aber so, dass zwischen den Strings plötzlich nicht mehr 0x00 sondern Zeichen wie 0x03, 0x04, 0x06 etc. gesendet werden. Zudem erhalte ich dann noch die Warnmeldung ../new10uart.c:52: warning: 'data' may be used uninitialized in this function Es wäre nett wenn mir jemand weiterhelfen könnte...ich weiß wirklich nicht mehr weiter! Grüße, Klaus
Ich bin gerade zu faul die Zeile 52 zu suchen. Markiere die mal bitte. Diese Mimik mit dem FIFO Head und Tail sieht merkwürdig aus, wenn die Buffergrössen keine Zweierpotenzen sind. Ich kenne mich mit der Lib von Peter Fleury nicht aus, habe mal reingeguckt und siehe da, gleich am Anfang von uart.c steht: " The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define the buffer size in bytes. Note that these variables must be a power of 2."
Der tiefere Grund ist, dass P. F. mit der Maskierungsoperation eine Modulo-Arithmetik erreicht. Er ersetzt also
1 | tmp_head = (uart0_rx_head + 1 ) % UART0_RX_BUFFER_MASK; |
durch
1 | tmp_head = (uart0_rx_head + 1 ) & UART0_RX_BUFFER_MASK; |
Der Grund ist, das letzteres schneller geht. Das ist nun der zweite Fall wo Dir das lesen der Unterlagen (einmal ein C-Buch, einmal die Beschreibung der Lib die Du einsetzen willst) geholfen hätte. Ich bitte Dich höflich, Dich in Zukunft mehr vorab zu informieren.
Hallo Guru,Danke für deine Antwort. Das mit der Maskierung ist mir durchaus bewusst, hab das im Code aber leider vergessen abzuändern. Sorry! Allerdings glaub ich den Fehler gefunden zu haben. Allerdings weiß ich nicht ob meine Interpretation dazu richtig ist. Die Funktion getc() wartet nicht bis ein Zeichen kommt. Gut, hier hab ich nur den Fall ( uart0_rx_head != uart0_rx_tail ) definiert, nicht aber wenn (uart0_rx_head == uart0_rx_tail) ist. Meine Annahme ist, dass mein uC aus diesem Grund willkürliche Zeichen sendet und teilweise abschmiert. unsigned int uart0_getc( void ) { unsigned char tmp_tail; unsigned char data; if( uart0_rx_head != uart0_rx_tail ) { tmp_tail = ( uart0_rx_tail + 1 ) & UART0_RX_BUFFER_MASK; uart0_rx_tail = tmp_tail; data = uart0_rx_buffer[tmp_tail]; } return data; } Aus diesem Grund muss ich für den Fall das uart0_rx_head == uart0_rx_tail ist einen Rückgabewert festlegen, das meinem Programm sagt, dass keine Zeichen vorhanden sind. Ich habe hier nun mal den Rückgabewert 0 festgelegt. Sprich in meinem Hauptprogramm kann ich nun mit if(getc != 0x00) die Nullen rausfiltern und erhalte meine Strings. unsigned int uart0_getc( void ) { unsigned char tmp_tail; unsigned char data; if( uart0_rx_head == uart0_rx_tail ) { return 0; } else { tmp_tail = ( uart0_rx_tail + 1 ) & UART0_RX_BUFFER_MASK; uart0_rx_tail = tmp_tail; data = uart0_rx_buffer[tmp_tail]; } return data; } Passt meine Überlegung soweit? Ich bin noch Anfänger und würde mich über jeden Tipp und Hinweis freuen.Grüße
>hab das im Code aber leider vergessen abzuändern. Sorry!
Eine Entschuldigung ist nicht nötig. Aber deswegen gibt es in der
Netiquette den Hinweis immer den Code zu posten, mit dem Du auch
arbeitest.
Schau Dir den Code von Peter Fleury an. Da ist auch ein getc dabei und
Du kannst sehen, was wann passiert.
Du schriebst doch, dass Du die Lib von Peter Fleury verwendest. Warum
erfindest Du jetzt getc neu? Warum musst Du nun den Rückgabewert nochmal
anders setzen als in dem Code von Peter? Wenn Du schon Anfäger bist,
dann lass doch den Code so wie er ist und versuche erstmal ihn zu
verstehen. Wenn Du ihn verstehst, dann sind auch Deine Änderungen daran
sinnvoller und Deine Fragen, verzeihe mir bitte, nicht so unnötig.
Vor allem: Was ist wenn Du mal eine 0x00 senden/empfangen willst?
Ich muss zugegeben, dass ich jetzt noch weniger Geduld habe als vorhin.
Es fällt mir schwer zu akzeptieren, das Du einerseits Peter Fleurys Lib
zu verwenden vorgibst, aber dann hier Fragen stellst, die unter der
Voraussetzung unnötig sind.
Wenn dann noch so Dinger kommen, wie: "Ach, sorry, das ist garnicht der
Code", dann nervt das zusätzlich.
Hmm. Veränderst Du deswegen die Fleury-Lib?
>Da die Übertragung meiner seriellen Daten (Gerät --> uC) länger dauert, als >die
Zeitspanne, in denen mein uC den FIFO leert, werden dazwischen 0x00 >gesendet.
Das musst Du mal genauer erklären.
Warum ist das ein Problem, wenn der uC die Daten schneller ausliest, als
der PC sie sendet?
Normalerweise ist das kein Problem. Wenn nicht genügend Daten da sind,
damit der uC damit was anfangen kann, dann lass ihn einfach warten, bis
genug Daten da sind. Das mit den Dummy-Nullen ist unnötig.
Ich hab mich da in irgend etwas verfangen und rein gesteigert. Im Grunde macht es wirklich keinen Sinn die Lib zu verändern. Allerdings kann ich beim Auftreten von.... #define UART_FRAME_ERROR 0x0800 /* Framing Error by UART */ #define UART_OVERRUN_ERROR 0x0400 /* Overrun condition by UART */ #define UART_BUFFER_OVERFLOW 0x0200 /* receive ringbuffer overflow */ ..meistens programmtechnisch ja eh nicht eingreifen. Allerdings kann ich sagen, dass wenn diese Fehler auftreten der String im Buffer nicht für die weitere Verarbeitung verwendet werden soll, was natürlich wiederum eine zusätzliche Sicherheit bedeuten würde. Mit der 0x00 hast du eigentlich auch Recht. chars haben ja eine Wertebereich von 0...255 mit... #define UART_NO_DATA 0x0100 /* no receive data available */ ...würde ich also drüber liegen und es käme zu keiner Fehlinterpretation. Wenn ein String mit Leezeichen gesendet wird, hab ich dann ein Problem. Danke für deine Antwort!
>Wenn ein String mit Leezeichen gesendet wird, hab >ich dann ein Problem. Was für ein Problem hast Du dann? Was Dir fehlt, denke ich, ist ein Konzept für das Protokoll und ein Schema für den Ablauf der Empfangsseite. Oder wie siehst Du das? Ich würde Dir empfehlen, einfach mal die P.F.-Lib (soweit wie möglich im Originalzustand) mit einem simplen Echo zum laufen zu bringen. Das übliche wäre auf der Empfängerseite eine Zustandsmaschine, die mit dem Startzustand beginnend, auf ein Startzeichen im Empfangsbuffer wartet, dann in den nächsten Zustand übergeht und dort Zeichen sammelt bis die richtige Anzahl an Zeichen empfangen worden ist. In einem dritten Zustand verarbeitest Du die Daten und gehst wieder in den Startzustand. (Man kann das parsen der Empfangsdaten auch als Zustände implementieren, aber das ist erst die nächste Komplexitätsstufe denke ich). Mit dieser Mimik nutzt Du den FIFO genau wie er gedacht ist. Nämlich zur Entkopplung der Erzeugungsgeschwindigkeit der Daten und deren Konsum durch den uC.
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.