From a3c116444200801e1fc1b81dca2b7f404f4a3e4d Mon Sep 17 00:00:00 2001 From: Paul Goeser Date: Fri, 13 Jan 2012 18:59:41 +0100 Subject: [PATCH] added ringbuffer from thermocouple-project --- TODO | 6 ++++- ringbuf_small.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ ringbuf_small.h | 18 ++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 ringbuf_small.c create mode 100644 ringbuf_small.h diff --git a/TODO b/TODO index ba1137c..17b9e30 100644 --- a/TODO +++ b/TODO @@ -3,8 +3,13 @@ - programmieren - sdcard + - timing von soft-spi + - streaming funktion - pwm + - 11bit-pwm-emu - drumherum + - data-streaming von sdcard + - ringbuf (ryx) - testen - sdcard @@ -19,5 +24,4 @@ == ryx == -- belastbarkeit von kleinen Tastern nachschlagen diff --git a/ringbuf_small.c b/ringbuf_small.c new file mode 100644 index 0000000..d848be9 --- /dev/null +++ b/ringbuf_small.c @@ -0,0 +1,66 @@ +#include "ringbuf_small.h" + +#include + + +/* Very generic implementation of an interrupt-safe ringbuffer + * + * Contention handling: + * - writing of pointers only with interrupt lock + * - reading of pointers allowed at any time + * - volatile not really necessary, unless you really need the functions to + * react to freespace/newdata while they're running + * + * PUT AND GET ARE NOT REENTRANT! + */ + +void ringbuf_init(ringbuf_t *rb, char* buf, int size){ + rb->startptr = buf; + rb->size = size; + rb->readpos = 0; + rb->writepos = 0; +} + +/* pushes a value onto the ringbuffer + * returns 0 on success, 1 on buffer full + */ +uint8_t ringbuf_put(ringbuf_t *rb, uint8_t value){ + // calculate next ptr pos + uint8_t next = rb->writepos + 1; + if(next >= rb->size){ + next = 0; + } + // check for space + if(next == rb->readpos){ + return(1); // give up + } + *(rb->startptr + rb->writepos) = value; + // do we need a barrier here? + rb->writepos = next; + return(0); +} + +/* gets a value from the ringbuffer + * returns value on success, -1 on buffer empty + */ +int16_t ringbuf_get(ringbuf_t *rb){ + uint8_t value; + uint8_t next; + // calculate next ptr pos + next = rb->readpos + 1; + if(next >= rb->size){ + next = 0; + } + //check for empty + if(rb->readpos == rb->writepos){ + return(-1); + } + value = *(rb->startptr + rb->readpos); + rb->readpos = next; + return(value); +} + + + + + diff --git a/ringbuf_small.h b/ringbuf_small.h new file mode 100644 index 0000000..ce6ff6b --- /dev/null +++ b/ringbuf_small.h @@ -0,0 +1,18 @@ +#ifndef __RINGBSML_H +#define __RINGBSML_H + +#include + +typedef struct { + char* startptr; + uint8_t size; + uint8_t readpos; + uint8_t writepos; +} ringbuf_t; + + +void ringbuf_init(ringbuf_t* rb, char* buf, int size); +uint8_t ringbuf_put(ringbuf_t *rb, uint8_t value); +int16_t ringbuf_get(ringbuf_t *rb); + +#endif