Immer wieder braucht man einen Fifo, wenn zeitlich unabhängige Prozesse untereinander Daten austauschen müssen. Die Berechnung eines Wertes ist z.B. schnell erledigt, wenn dieser Wert aber über die serielle Schnittstelle verschickt werden (oder auch auf einem Display ausgegeben werden) muß, ist es unsinnig, auf das Übertragungsende jedes Zeichens zu warten.
Also wird der Wert von einer Routine berechnet und anschließend in einen Pufferspeicher abgelegt. Eine andere, zeit- oder interruptgesteuerte Routine holt dann ein Zeichen nach dem anderen aus dem Puffer und versendet das Zeichen.
Einfach und effizient zu implementieren ist ein Fifo, dessen Größe einer 2er-Potenz entspricht (8, 16, 32, 64...). Dann kann der Indexüberlauf einfach mit einer Bitmaske abgehandelt werden. Hier ist so eine Implementierung:
#define BLEN (16) // z.B. 16 #define BMSK (BLEN-1) // z.B. 16-1 = 15 = binär 1111 typedef struct { volatile unsigned char w; volatile unsigned char r; unsigned char d[BLEN]; // die Daten sind nicht volatil, sie können sich } fifotyp; // nur geändert haben, wenn der Index sich ändert fifotyp fifo; : : // Fifo schreiben if ((fifo.w - fifo.r)&BMSK==BMSK) { // Fehlerbehandlung: Fifo ist voll } else { // Zeichen eintragen fifo.d[fifo.w&BMSK] = din; fifo.w++; } // Fifo lesen if (fifo.w != fifo.r) { // Fifo belegt? // Zeichen auslesen dout = fifo.d[fifo.r&BMSK]; fifo.r++; } // Fifo leeren fifo.w = fifo.r
Fifo leer: Wenn der Leseindex r gleich dem Schreibindex w ist, dann ist der Fifo leer.
Fifo belegt: Wenn der Leseindex r ungleich dem Schreibindex w ist, dann ist ein Zeichen im Puffer. Wichtig ist, dass zuerst das Zeichen in den Puffer geschrieben (bzw. gelesen) wird, und erst dann der Index erhöht wird. Denn sonst könnte nach der Indexmanipulation ein Interrupt kommen, und weil das Zeichen noch nicht eingetragen wurde, wird mit falschen Daten gearbeitet.
Fifo Reset: Das Rücksetzen des Fifos erfolgt einfach, indem der Leseindex gleich dem Schreibindex gesetzt wird. Allerdings sollte dieser Vorgang nur im Notfall angewendet werden, denn dabei gehen garantiert irgendwelche gespeicherte Informationen verloren.
Fifo Overrun: Ob noch ein Zeichen in den Fifo passt oder dieser voll ist, kann durch die Subtraktion des Schreibindex w vom Leseindex r überprüft werden. Ist das Ergebnis dieser Operation -1, dann kann kein weiteres Zeichen gespeichert werden. Aber aufpassen: weil beide Indexe unsigned sind, muss auf (BLEN-1 = BMSK = alle Bits auf 1) abgefragt werden.