Forum: Projekte & Code Kleine FIFO Lib


von Falk B. (falk)


Lesenswert?


von chris (Gast)


Lesenswert?

Der buffer type sollte fifo_t sein und nur definiert werden wenn ifndef 
...
Ansonsten ist es eben nicht universell verwendbar.

von Falk B. (falk)


Lesenswert?

???

Ich verstehe nicht, was du meinst.

Ach ja, ich bin nur für den Abschnitt verantwortlich, nicht was da 
drüber oder drunter steht.

von Jim M. (turboj)


Lesenswert?

Übrigens war das FIFO_write Macro kaputt, ich habe das mal korrigiert.

Langversion:

Das FIFO_write Macro schrieb zuerst den Index, dann die Daten. Das ist 
falsch herum: Falls ein Leser den Schreiber genau nach dem Schreiben des 
Index unterbricht, bekommt er den alten Wert statt dem neuen.

von Falk B. (falk)


Lesenswert?

@ Jim Meba (turboj)

>Übrigens war das FIFO_write Macro kaputt, ich habe das mal korrigiert.

Welches denn bitte? In dem Artikel fliegen viele Versionen rum!

HIER geht es nur um MEINE Lib!

https://www.mikrocontroller.net/wikifiles/f/fd/Fifo.zip

Und da gibt es keine Macros, nur Funktionen.

>Langversion:

>Das FIFO_write Macro schrieb zuerst den Index, dann die Daten. Das ist
>falsch herum: Falls ein Leser den Schreiber genau nach dem Schreiben des
>Index unterbricht, bekommt er den alten Wert statt dem neuen.

Diese Macrofrickelei ist so oder so NICHT interruptfest, also kann das 
Makro eigentlich nur vom Hauptprogramm aus genutzt werden und da unter 
bricht niemand. Schön ist dieses "Beispiel" so oder so nicht. Ich wollte 
es fast schon löschen.

von chris (Gast)


Lesenswert?

Gerade das Zip file angesehen.
Bedingt ISR safe, lizenz ist gpl 2+ , demo ist gpl 3, braucht -std=c99

Beispiel folgender code.
Man liest 4 fifo bloecke. Diese werden sofort freigegeben, und dann
von einem Interrupt gleich follgeschrieben, befor der read pointer 
welcher
zurueckgegeben wird ueberhaupt gelesen werden kann.
Gluecklicherweise ist die Funktion "void", also macht sich nicht
"read burst" sondern "drop count" , wobei aber auch wieder der Index 
falsch
ist. Angenommen fifo read is auf der letzten Position im Buffer,
und es wird read_bursted(fifo_in,3) aufgerufen, dann ist der Index 
falsch,
denn der Index wird nicht corrigiert, sondern einfach brachial auf 
fifo->base gesetzt. Kann funktionieren, aber gerade bei solchen 
wichtigen
und basis Libs sollte es besser codiert sein.

void fifo_read_bursted(fifo_t *fifo, fifo_size_t count) {
    fifo_data_t* tmp;

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
        tmp = (fifo_data_t*)fifo->read_p + count;

        if (tmp > fifo->top) {
            fifo->read_p = fifo->base;
        } else {
            fifo->read_p = tmp;
        }
    }
}

von Falk B. (falk)


Lesenswert?

@ chris (Gast)

>Bedingt ISR safe, lizenz ist gpl 2+ , demo ist gpl 3, braucht -std=c99

Jaja, ich weiß ja das Techniker keine Literaten sind, aber ein paar 
allgemeinverständliche, geschlossene Sätze wäre schon nicht schlecht, 
oder?

Die GPL ist kopiert aus einem anderen Projekt, hab ehrlich gesagt nicht 
wirklich drüber nachgedacht. Meinetwegen mach ich ne beerware Lizenz 
draus.

Dein Schreibstil ist wirr. Bist du ein Unix-Freak?

>Man liest 4 fifo bloecke. Diese werden sofort freigegeben, und dann
>von einem Interrupt gleich follgeschrieben, befor der read pointer
>welcher
>zurueckgegeben wird ueberhaupt gelesen werden kann.
>Gluecklicherweise ist die Funktion "void", also macht sich nicht
>"read burst" sondern "drop count" , wobei aber auch wieder der Index
>falsch
>ist. Angenommen fifo read is auf der letzten Position im Buffer,
>und es wird read_bursted(fifo_in,3) aufgerufen, dann ist der Index
>falsch,

Der Aufruf ist schon falsch. Eine Burst kann sinnvollerweise NIE über 
den Überlauf gehen, sondern maximal bis zum Ende. Steht auch so im 
Beispiel. Und dort steht nicht umsonst, mach es IMMER so!

>denn der Index wird nicht corrigiert, sondern einfach brachial auf
>fifo->base gesetzt. Kann funktionieren, aber gerade bei solchen
>wichtigen
>und basis Libs sollte es besser codiert sein.

Was ist daran falsch kodiert? Die Burst-Korrektur greift immer nur auf 
den "zugehörigen" Pointer. Sprich, es gibt im allegmeinen nur einen 
Softwareteil (z.B. FSM im Hauptprogramm) welcher schreibt und ein 
anderer (ISR) welcher liest. Die beiden Seiten greifen nicht schreibend 
auf den Pointer der Gegenseite zu!

>void fifo_read_bursted(fifo_t *fifo, fifo_size_t count) {
>    fifo_data_t* tmp;

>    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
>        tmp = (fifo_data_t*)fifo->read_p + count;

>        if (tmp > fifo->top) {
>            fifo->read_p = fifo->base;
>        } else {
>            fifo->read_p = tmp;
>        }
>    }
>}

Das ist der originale Code. Was ist daran falsch?

Klar kann ein "Experte" unqualifiziert an den Pointern rumfummeln, aber 
das ist nicht das Thema. Wenn man nur die Funktionen sinngemäß nutzt, 
sollte es passen.

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.