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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Techniker (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


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

mfg

von Techniker (Gast)


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

von Barrex (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Mir fehlt die Idee wie ich dies bei mir richtig umsetzen kann.

von Adam P. (adamap)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Ok stimmt, das ist verwirrend.

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

von Peter D. (peda)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Nur so nebenbei bemerkt:

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

von Techniker (Gast)


Bewertung
0 lesenswert
nicht 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. (achs)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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 ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.