Hallo, ich habe mir mal zwei Funktionen geschrieben, um Werte in einen Ringspeicher zu schreiben und zu lesen. Leider habe ich bei meinem Programm einen Speicherplatz im Ringpuffer verschwendet, um beim Lesen feststellen zu können dass der Speicher leer ist. Mit ein paar zusätzlichen Abfragen und einer zusätzlichen Variablen in der Funktion zum Ringspeicher auslesen ließe sich das sicher anders realisieren. Wenn der Ringspeicher jedoch nur 16Bit Integer-Werte aufnimmt, ist ja abzuwägen was im Speicher weniger Platz wegnimmt. Vielleich hat ja jemand noch einen eleganteren Code. Hier meine Funktionen: void schreibeRS(int wert) { ringspeicher[schreibepointer++] = wert; if (schreibepointer >= SPEICHERGROESSE) schreibepointer = 0; if (schreibepointer >= SPEICHERGROESSE) schreibepointer = 0; if (schreibepointer == lesepointer) lesepointer++; if (lesepointer >= SPEICHERGROESSE) lesepointer = 0; } //------------------------------------------------- int leseRS(void) { int wert; wert = ringspeicher[lesepointer]; if (lesepointer == schreibepointer) wert = LEER; else { lesepointer++; if (lesepointer >= SPEICHERGROESSE) lesepointer = 0; } return wert; }
Hi, Thomas, wozu selber erfinden, was andere schon zur Perfektion gebracht und nicht geschützt haben? Googele mal unter "UART", "header", "trail", da findest wohl Dutzende Beispiele. Besonders elegant fand ich die, wo der Ringpuffer eine Größe von 4, 8, 16, 32 etc. hat, weil Du den Überlauf mit einer Und-Funktion verhindern kannst. Ciao Wolfgang
> if (schreibepointer >= SPEICHERGROESSE) > schreibepointer = 0; > if (schreibepointer >= SPEICHERGROESSE) > schreibepointer = 0; Wozu zweimal? oder nur ein Copy&Paste Fehler ?
Hallo schau mal bei den AVR Application Notes nach AVR306 (bitte pdf und Source ansehen). http://www.atmel.com
Danke, die Atmel Application Note sieht gut aus. Der Puffer funktioniert da so wie von Wolfgang oben schon beschrieben. Allerdings muss man erst zweimal hinschauen um das zu verstehen. Bei meinem "Prototypen" ist es ja etwas einfacher zu verstehen, aber halt nicht ganz so sparsam. @Malte: Ist wohl irgendwie doppelt reingerutscht, die doppelte Abfrage macht natürlich keinen Sinn. Thomas
Ich benutze für solche Puffer Makros: // increment for ring buffer index (0..n-1), also works with start value -1 # define mc_RING_INC(x, n) {++(x); (x) %= (n);} // next value at incrementing # define mc_RING_NEXT(x, n) (((x)+1)%(n)) // decrement for ring buffer index (0..n-1), also works with start value < 0 # define mc_RING_DEC(x, n) {if((x) > 0) --(x); else (x)=(n)-1;} // value before last increment # define mc_RING_LAST(x, n) ( (x) ? ((x)-1) : ((n)-1)) Für einen AD-Wandler in einem ARM9 habe ich damit mal Ringpuffer (für jeden Kanal einen) programmiert, aus deren 64-Bit-Index man jeweils sowohl den letzten Ringpufferindex als auch dessen Zeit (seit dem Treiber-Start) entnehmen kann, damit man die Daten aus den Puffern lückenlos und ohne Überlappungen auslesen kann.
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.