Inspiriert von dem einfachen 2ⁿ-FIFO Beispiel aus unserem wiki habe ich schnelle FIFO mit erweitertem Funktionsumfang erstellt. Funktionen: - basiert auf Macros - generisch: jede FIFO kann einen beliebigen Datentyp speichern - flexible Größe: jede FIFO kann eine beliebige 2ⁿ Länge haben (n < 2^16) - minimaler RAM benötigt - einfach: alle FIFO-typischen Funktionen sind verfügbar, Beispielcode ist vorhanden - MIT-lizensiert Der Code und eine etwas ausführlichere Beschreibung ist auf https://github.com/nqtronix/fifofast gehosted. Alle marcos der aktuellen Version 0.2.0 sind getestet und funktionieren wie erwartet. Vorherige Versionen (bevor ich git genutzt habe) sind bereits seit etwa einem Jahr problemlos in Verwendung. Ich plane noch einige Features und Performanceoptimierungen, wollte aber diese vorläufige Version schon mal mit euch teilen, da sie imho einige Vorteile zu der Variante aus dem wiki besitzt. Falls ihr Verbesserungsvorschläge oder generelles Feedback habt könnt ihr das gerne hier posten, für Bugs macht bitte ein Issue auf github auf. Grüße Dennis Edit: Titel bearbeitet
:
Bearbeitet durch User
Eine gute Demonstration, warum C++ templates erfunden wurden... Duck und wech
Dr. Sommer schrieb: > Eine gute Demonstration, warum C++ templates erfunden wurden... Da stimm ich dir zu, für C++ Code sind templates die bessere Wahl. Für C muss man halt kreativ werden schulterzuck
Dennis . schrieb: > Für C muss man halt kreativ werden schulterzuck Oder sich überlegen ob man wirklich unbedingt C braucht...
Hab in den letzten Tagen an fifofast weiter gearbeitet und um folgende Features ergänzt: - Readme komplett überarbeitet (mit vielen Beispielen!) - automatisiertes Testen des Quellcodes - inline Funktionen, um auf Fifos per pointer zugreifen zu können - fifo arrays, falls man mehr als 1 Fifo von der gleichen Art braucht Wie gehabt ist der Code auf https://github.com/nqtronix/fifofast gehostet.
Ich habe hierbei den seltsamen Fall, dass bei 2 FIFOs gleichen Datentyps und Länge es zu seltsamen Effekten kommt. Der zweite FIFO scheint in einen anderen Rambereich zu schreiben und es kommt zu Problemen woanders im Programm. So siehts bei mir aus: _fff_declare(uint16_t, fifo_uint16_1, 128); _fff_declare(uint16_t, fifo_uint16_2, 128); _fff_init(fifo_uint16_1); _fff_init(fifo_uint16_2); Im Code nutze ich die Funktion _fff_write zum Schreiben und _fff_read zu Lesen der Daten. Habe ich hier etwas nicht verstanden? Viele Grüße
Die declare/init Makros deklarieren und initialisieren die anonyme structs mit den von dir gewählten Namen (fifo_unit16_1/2). Die anderen Makros greifen auf diese structs mit Namen zu. Die structs nutzen natürlich unterschiedliche RAM Adressen, und sollten sich gegenseitig nicht beeinflussen. Falls du auf eine fifo auf verschiedenen .c Dateien zugreifst: Die "declare" muss in einen .h Header Datei, die von allen relevanten .c Dateien inkludiert wird. Die init nur 1x in einer .c Datei aufrufen. Ansonsten erzeugt du mehrere structs mit gleichem Namen. Falls du auf eine fifo aus Interrupt UND regulären Funktionen zugreifst: Entweder im Interrupt befüllen und im normalen code auslesen, oder umgekehrt. Niemals von beiden Stellen gleich zugreifen.
Hi, Danke für deinen Kommentar. Beide Declare und Init Makros sind in einer .c Datei global angelegt. Das befüllen der FIFOs mit write geschieht nicht im Interruptkontext, werden aber durch das deaktivieren und aktivieren der Interrupts geschützt. Das Lesen passiert auch in der gleichen Datei, gekapselt durch eine Get-Funktion, sodass ich die Daten von woanders über die Get-Funktion auslesen kann. Zuerst wird aber durch _fff_mem_level überprüft, ob überhaupt Daten vorhanden sind. Danach werden sie durch read ausgelesen. Ich kann jetzt nicht den echten Code präsentieren, aber das prinzipielle. Das ganze läuft auf einem STM32 ARM M3 Core.
1 | _fff_declare(uint16_t, fifo_uint16_1, 128); |
2 | _fff_declare(uint16_t, fifo_uint16_2, 128); |
3 | |
4 | _fff_init(fifo_uint16_1); |
5 | _fff_init(fifo_uint16_2); |
6 | |
7 | void WriteFifo(uint16_t data_1, uint16_t data_2) |
8 | { |
9 | __disable_irq(); |
10 | //_fff_write_(fifo_uint16_1, 0); |
11 | //_fff_write_(fifo_uint16_2, 0); |
12 | __enable_irq(); |
13 | } |
14 | |
15 | uint16_t GetFifoData(uint8_t* pData, uint8_t fifo) |
16 | { |
17 | uint16_t tmp = 0; |
18 | uint16_t i = 0; |
19 | uint16_t mem_level = 0; |
20 | |
21 | if(fifo == 1) |
22 | { |
23 | mem_level = _fff_mem_level(fifo_uint16_1); |
24 | } |
25 | else |
26 | { |
27 | mem_level = _fff_mem_level(fifo_uint16_2); |
28 | } |
29 | |
30 | for(i = 0; i < mem_level*2; i+=2) |
31 | { |
32 | if(ka == 1) |
33 | { |
34 | tmp = _fff_read (fifo_uint16_1); |
35 | } |
36 | else |
37 | { |
38 | tmp = _fff_read (fifo_uint16_2); |
39 | } |
40 | memcpy(&pData[i], &tmp, 2); |
41 | } |
42 | |
43 | return i; |
44 | } |
-> Sollte doch alles so in Ordnung sein? Edit: Ich überlege gerade, ob ich durch memcpy einen Bock verbaue? Hm... Ansonsten probiere ich mal mit Arrays aus _fff_declare_a
:
Bearbeitet durch User
Hi, das Problem liegt auf meiner Seite, nicht an dem fifo. Nur als Info. Viele Grüße
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.