Hallo, aufgrund eines schnellen datenaufkommens von seitens der UDP-Kommunikation (PC-> Mikrocontroller) auf einem Mikrocontroller, soll ein Software FIFO in die bestende UART-Kommunikation integriert werden. Für das Senden von UART Frames gibt es eine Methode mit der ein Interrupt getriggert wird. In der UART Interruptroutine werden nacheiander die Daten vom UartBuffer versendet. Danach wird der Trigger wieder deaktiviert bis wieder die Send Methode ausgeführt wird. Das Software FIFO kann insgesamt 10 Frames von der Länge 200 Bytes speichern.
Das ist schön und wird deine Applikation sicher um einiges, den Anforderungen entsprechend, schöner machen. Was ist jetzt dein Problem? :)
Ist das jetzt die Fortführung von diesem Thread? Beitrag "Mikrocontroller: Ringpuffer für UART-Kommunikation" mfg
Mir geht es eigentlich darum, wie so ein Software FIFO in die bestehende UART integriert werden kann.
In der Regel sollte es beim UART ein Flag(Bit) geben, welches anzeigt ob das letzte Byte gesendet wurde. Dieses Flag überprüfst du in der Schleife des Hauptprogramms. Ist der UART bereit das nächste Byte zu senden, liest du dieses aus den FIFO und übergibst es dem UART. Unabhängig davon schreibst du neue zu sendende Bytes in den FIFO.
Techniker schrieb: > Mir geht es eigentlich darum, wie so ein Software FIFO in die bestehende > UART integriert werden kann. Z.B.: Beitrag "AVR-GCC: UART mit FIFO"
Vergiss dir nicht zu überlegen, was bei einem Überlauf des FIFOs passieren muss. Überschreibst du ältere Bytes oder übernimmst du keine neuen Bytes mehr in den FIFO? Das musst Du je nach den Anforderungen Deiner Anwendung selbst festlegen.
Nur als kurzer Hinweis. Die Lösung von Peter arbeitet mit Interrupts. Ich hatte in meinem Posting eine Pollinglösung im Kopf.
Vielen Dank für eure Hilfe. Vorgehensweise: --> Send Methode werden die ankommenden Daten von UDP in das FIFO abgelegt --> In der Hauptschleife wird geprüft ob die UART noch sendet oder nicht. Wenn die UART frei ist soll der Sende-Interrupt getriggert werden. Hier wird dann das erste Element vom FIFO versendet. Was passiert wenn nun mehrere Elemente im FOF vorhanden sind. Sollen dann alle Elemente auf einmal versendet werden?
Ich n nun dabei Code von Peter Dannegger zu verstehen und das Prinzip auf meiner Anwendung zu integrieren. Folgendes ist mir unklar: In der while-Schleife vom Hauptprogramm wird mit der Funktion uputchar0 Datenhinzugefügt. Welche Funktion hat dabei die Funktion utx0_ready?
Techniker schrieb: > Welche Funktion hat dabei die Funktion utx0_ready? uputchar0 wartet, wenn kein Puffer mehr frei ist. utx0_ready prüft, ob mindestens 1 Byte Puffer frei ist.
> Sollen dann alle Elemente auf einmal versendet werden?
Verwechsele die Begriffe nicht. UART Schnittstellen senden Bytes (oder
Zeichen). Ein Element kann alles mögliche sein, zum Beispiel ein Stück
von einem Videoclip.
Und da sie ein Byte nach dem andere heraus schieben, kann man gar nicht
mehrere Bytes auf einmal senden. Du kannst nicht einmal ein Element am
Stück senden, wenn es aus mehr als einem Byte besteht.
Ich habe ein FIFO indem Frames gespeichert werden. Der Inhalt eines Frames das aus mehreren Bytes besteht wird nacheinander von der UART versendet.
Folgende Funktionen gibt es in meiner Applikation: - Sendefunktion --> Hier werden die ankommenden Frames in ein FIFO abgelegt - AppendFrameToFIFO --> Diese Funktion wird in der Sendefunktion ausgeführt - Operate Methode --> Diese Methode wird im Hauptprogramm in der while-Schleife ausgeführt - Sende Service Interruptroutine
Mir fehlt die Idee wie ich dies bei mir richtig umsetzen kann.
C Pseudo-Code: Ich finde deine Aufteilung noch nicht ganz so geschickt, aber habe versucht diese zu beachten. Vllt. hilft es dir auf die Sprünge ;-)
1 | /****************************************/
|
2 | ISR_UART() |
3 | {
|
4 | /**
|
5 | * Status Bit aus dem UART Register,
|
6 | * TX ist bereit zum Senden.
|
7 | */
|
8 | if(uart_get_status() & UART_TX_READY) |
9 | {
|
10 | if(fifo_is_empty() == false) |
11 | {
|
12 | byte = fifo_get_byte(); |
13 | uart_send(byte); |
14 | }
|
15 | else
|
16 | {
|
17 | // TX Interrupt deaktivieren
|
18 | uart_disable(); |
19 | }
|
20 | }
|
21 | }
|
22 | |
23 | /****************************************/
|
24 | void send_frame_data() |
25 | {
|
26 | if(new_frame == true) |
27 | {
|
28 | append_frame_to_fifo(); |
29 | |
30 | // TX Interrupt aktivieren
|
31 | uart_enable(); |
32 | }
|
33 | }
|
34 | |
35 | /****************************************/
|
36 | void main() |
37 | {
|
38 | while(1) |
39 | {
|
40 | operate(); |
41 | |
42 | send_frame_data(); |
43 | }
|
44 | }
|
:
Bearbeitet durch User
Hallo Adam, danke für das Beispiel! In deinem Beispiel wird die send_frame_data permanent ausgeführt. In meiner Applikation wird je nach Ereignis die Send Methode ausgeführt.
Ja kannst du ja implementieren, wie es dir am besten passt, aber ich würde sie nicht "send" nennen, da sie nicht sendet. Der Ablauf ist doch wie folgt: - operate() - evtl. create_frame() - append_frame_to_fifo() - start_send() / enable_uart() - read_fifo() / fifo_get_byte() Eine Fkt. "send" zu nennen und in dieser aber den Frame lediglich in FIFO schreiben, ist etwas verwirrend.
:
Bearbeitet durch User
Ok stimmt, das ist verwirrend. Welchen Ablauf müsste ich in der while-Schleife (operate-Methode) umsetzen?
Man kann sich ja eine Funktion schreiben, die anhand der Indizes die Anzahl freier Bytes berechnet. Und wenn diese kleiner als ein Frame ist, wird der Frame verworfen. Damit vermeidet man das Warten, bis das vorherige Senden beendet ist. Will man keine Frames verlieren, muß man aber warten, und das macht uputchar0 schon von sich aus. Oder man erzeugt mit einem Timer oder Sheduler die Frames nicht schneller, als sie gesendet werden können.
Techniker schrieb: > Welchen Ablauf müsste ich in der while-Schleife (operate-Methode) > umsetzen? Das hängt doch davon ab, was du machen möchtest... Daten einlesen (AD Wandler, andere Schnittstellen), Daten verarbeiten, Daten in ein Frame verpacken, Frame in FIFO schieben, Senden aktivieren.
Nur so nebenbei bemerkt: Wenn man warten muss und es akzetabel ist, immer zu warten, dann braucht man keinen Sendepuffer.
Hallo Peter in deiner Implementierung werden die Daten byteweise in das FIFO geschrieben und wieder gelesen. Meine Implementierung ist etwas anders. Ich bekomme von der UDP-Kommunikation Daten in Form eines Frames die in ein FIFO gespeichert werden. Das Versenden eines FIFO Eintrage ist quasi ein Frame mit einer bestimmten Anzahl von Bytes. Diese Bytes werden dann in der Interruptroutine nacheinander von der UART versendet.
Hier mal ein Fifo von 255 Byte ;-) Put: Aufruf mit [0..255]. Rückgabe -1 wenn voll. Get: Aufruf mit -1. Rückgabe -1 wenn leer Put oder Get ist interruptfest, wenn ++ atomar ist.
1 | typedef unsigned char BYTE; /* sieht schlanker aus |**/ |
2 | int Fifo(int b) |
3 | {
|
4 | static BYTE d[256]; |
5 | static volatile BYTE w=0, r=(BYTE) -1; |
6 | |
7 | return b<0?(BYTE)(1+r)==w?-1:d[++r]:r==w?-1:(d[w++]=b,0); |
8 | }
|
Die C-Datei enthält ein lauffähiges Beispiel ;-)
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.