www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Ringpuffer besser programmieren?


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;
}

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Malte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>   if (schreibepointer >= SPEICHERGROESSE)
>      schreibepointer = 0;
>   if (schreibepointer >= SPEICHERGROESSE)
>      schreibepointer = 0;

Wozu zweimal? oder nur ein Copy&Paste Fehler ?

Autor: jozi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

schau mal bei den AVR Application Notes nach AVR306 (bitte pdf und
Source ansehen).

http://www.atmel.com

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.