Forum: Mikrocontroller und Digitale Elektronik Anfängerfrage FIFO Befüllung


von Christi (Gast)


Lesenswert?

Hallo ich habe gerade mit der Programmierung angefangen. Ich habe da 
eine Frage zu einem sogenannten Buffersystem. Wie kann ich das unten 
gezeigte Befüllen eines Buffers in C anders realisieren? SO das ich mit 
Stringfunktionen den Inhalt kontrollieren kann. VG


buffer[0] = buffer[1];
buffer[1] = buffer[2];
buffer[2] = buffer[3];
buffer[3] = buffer[4];
buffer[4] = buffer[5];
buffer[5] = buffer[6];
buffer[6] = buffer[7];
buffer[7] = buffer[8];
buffer[8] = buffer[9];
buffer[9] = getc;

von Sam .. (sam1994)


Lesenswert?

Man schiebt normalerweise nicht den ganzen Buffer durch. Man nimmt eine 
Variable, die den Start des FIFOs definiert.

Beispiel mit 4fach FIFO

1,2,3,4  start=0  item entfernen
1,2,3,4  start=1  7 hinzufügen
7,2,3,4


damit nicht ungewollt elemente im FIFO sind muss man natürlich immer 
noch die aktuelle Länge mit definieren.

von Christi (Gast)


Lesenswert?

Danke für die Antwort!

buffer[0] = buffer[1];
buffer[1] = buffer[2];
buffer[2] = buffer[3];
buffer[3] = buffer[4];
buffer[4] = buffer[5];
buffer[5] = buffer[6];
buffer[6] = buffer[7];
buffer[7] = buffer[8];
buffer[8] = buffer[9];
buffer[9] = getc;

was ich hier nicht ganz verstehe, getc holt das Zeichen vom Uart und 
übergibt es dem Buffer. Mit jedem weiteren Zeichen, werden dann die 
vorher empfangenen weiter nach vorne geschoben, oder?! ich kapiere das 
immer noch nicht so ganz.

von Oliver J. (skriptkiddy)


Lesenswert?

Google mal nach
Ringbuffer

Gruß Skriptkiddy

von Sam .. (sam1994)


Lesenswert?

Das ganze verschieben, das du machen willst, dauert viel zu lange. Dein 
FIFO ist so etwas wie ein Ringbuffer.

Wenn du ein Zeichen abholst wird die Länge um eins reduziert und der 
Start(pointer) um eins erhöht.
1
#define LEN 16
2
uint8_t buffer[LEN];
3
4
uint8_t len = 0;
5
uint8_t start = 0;
6
7
void add(uint8_t item)
8
{
9
  uint8_t i = len + start;
10
  if(i >= LEN)
11
    i -= LEN;
12
  buffer[i] = item;
13
  if(len != LEN)
14
     len++;
15
}
16
uint8_t pop()
17
{
18
  if(len == 0)
19
    return 0;
20
  len--;
21
  uint8_t ret = buffer[start];
22
  if(++start >= LEN)
23
    start -= LEN;
24
  return ret;
25
}

Ich hab mal ein kleines Beispiel geschrieben. Keine Garantie auf 
Fehlerlosigkeit.

von pedro (Gast)


Lesenswert?

Normalerweise mache ich ein FIFO mit Pointer und Array, ein Pointer 
zeigt an die aktuelle Füllposition, einer an der auszulesenden Stelle. 
Man muss bloss absichern, dass sich die Pointer nicht überholen oder man 
auslesen will obwohl das Array leer ist.

von Guru (Gast)


Lesenswert?

>ich kapiere das immer noch nicht so ganz.
Ja. Das kann verwirrend sein.

>Mit jedem weiteren Zeichen, werden dann die vorher empfangenen weiter nach >vorne 
geschoben

Das wäre die wörtliche Umsetzung des Konzeptes. Aber... da das bedeuten 
würde die Daten wirklich jedesmal umzukopieren macht man das anders.

Nimm mal an, das folgende sei eine Abbildung des Speichers und der soll 
Teil unseres FIFOs sein.

buffer[0]
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]

Dann nimmt man sich zwei Indizes (, zwei Adressen, wenn Du so willst) 
und lässt sie in diesen Bereich zeigen.

Am Anfang, wenn noch nichts drin ist, zeigen beide auf die selbe 
Position. (Das kann eigentlich jede beliebige sein).

buffer[0]    <= LesePosition = Schreibposition = 0
buffer[1]
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]

Wenn nun ein Zeichen von der Schnittstelle gelesen wird, dann wird 
dieses an die aktuelle Schreibposition gespeichert und die 
Schreibposition um eins erhöht.

buffer[0]  = getc  <= LesePosition = 0
buffer[1]          <= Schreibposition = 1
buffer[2]
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]

Kommt nun noch ein Zeichen passiert wieder das gleiche.

buffer[0]  = 'x'  <= LesePosition = 0
buffer[1]  = getc
buffer[2]         <= Schreibposition = 2
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]


OK?

Lesen tut man immer das zuerst reingeschrieben Zeichen, also das älteste 
Zeichen. Man liest an der Leseposition. (Nomen est omen) und erhöht den 
Lesezeiger, damit man beim nächstenmal eben das nächste Zeichen liest.

buffer[0]  = 'x'
buffer[1]  = <= LesePosition = 1
buffer[2]         <= Schreibposition = 2
buffer[3]
buffer[4]
buffer[5]
buffer[6]
buffer[7]
buffer[8]
buffer[9]

Zeigen nun die Lese und die Schreibposition auf das selbe Element dann 
ist nichts im Fifo drin.

Das ist noch nicht ganz alles, weil man bei der Position 9 wieder zu 0 
muss und weil man prüfen muss ob die Schreibposition nicht die 
Leseposition erreicht, aber im groben sollte es klar sein.

Oder?

von Sam .. (sam1994)


Lesenswert?

Pointer geht natürlich auch. Aber ich glaube nicht, dass es dadurch viel 
schneller ist.

Wichtig ist: Es gibt immer 2 Möglichkeiten etwas zu verschieben. A: Man 
verschiebt alles oder B man verschiebt den Ursprung.

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.