Forum: Mikrocontroller und Digitale Elektronik Software FIFO für UART Kommunikation


von Techniker (Gast)


Lesenswert?

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.

von nicht"Gast" (Gast)


Lesenswert?

Das ist schön und wird deine Applikation sicher um einiges, den 
Anforderungen entsprechend, schöner machen.

Was ist jetzt dein Problem? :)

von Felix F. (wiesel8)


Lesenswert?

Ist das jetzt die Fortführung von diesem Thread? 
Beitrag "Mikrocontroller: Ringpuffer für UART-Kommunikation"

mfg

von Techniker (Gast)


Lesenswert?

Mir geht es eigentlich darum, wie so ein Software FIFO in die bestehende 
UART integriert werden kann.

von Barrex (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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"

von Barrex (Gast)


Lesenswert?

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.

von Barrex (Gast)


Lesenswert?

Nur als kurzer Hinweis. Die Lösung von Peter arbeitet mit Interrupts. 
Ich hatte in meinem Posting eine Pollinglösung im Kopf.

von Techniker (Gast)


Lesenswert?

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?

von Techniker (Gast)


Lesenswert?

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?

von Peter D. (peda)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

>  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.

von Techniker (Gast)


Lesenswert?

Ich habe ein FIFO indem Frames gespeichert werden. Der Inhalt eines 
Frames das aus mehreren Bytes besteht wird nacheinander von der UART 
versendet.

von Techniker (Gast)


Lesenswert?

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

von Techniker (Gast)


Lesenswert?

Mir fehlt die Idee wie ich dies bei mir richtig umsetzen kann.

von Adam P. (adamap)


Lesenswert?

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
von Techniker (Gast)


Lesenswert?

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.

von Adam P. (adamap)


Lesenswert?

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
von Techniker (Gast)


Lesenswert?

Ok stimmt, das ist verwirrend.

Welchen Ablauf müsste ich in der while-Schleife (operate-Methode) 
umsetzen?

von Peter D. (peda)


Lesenswert?

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.

von Adam P. (adamap)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

Nur so nebenbei bemerkt:

Wenn man warten muss und es akzetabel ist, immer zu warten, dann braucht 
man keinen Sendepuffer.

von Techniker (Gast)


Lesenswert?

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.

von A. S. (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.