https://www.mikrocontroller.net/articles/FIFO#FIFO_als_Bibliothek https://www.mikrocontroller.net/wikifiles/f/fd/Fifo.zip
Der buffer type sollte fifo_t sein und nur definiert werden wenn ifndef ... Ansonsten ist es eben nicht universell verwendbar.
??? Ich verstehe nicht, was du meinst. Ach ja, ich bin nur für den Abschnitt verantwortlich, nicht was da drüber oder drunter steht.
Ü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.
@ 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.
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; } } }
@ 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.