ringbuf initial version

master
Paul Goeser 15 years ago
parent 29b5a85d34
commit cdbac9c8a5

@ -0,0 +1,11 @@
#include "ringbuffer.h"
ringbuf_t foo;
char buf[22];
int main(){
ringbuf_init(&foo,buf,sizeof(buf));
}

@ -0,0 +1,77 @@
#include "ringbuffer.h"
#include <util/atomic.h>
/* 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->endptr = buf+size;
rb->readpos = buf;
rb->writepos = buf;
}
/* 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
char* next = rb->writepos + 1;
char* readpos;
if(next >= rb->endptr){
next = rb->startptr;
}
// check for space
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
readpos = rb->readpos;
}
if(next == readpos){
return(1); // give up
}
*(rb->writepos) = value;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
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;
char* next;
char* writepos;
// calculate next ptr pos
next = rb->readpos + 1;
if(next >= rb->endptr){
next = rb->startptr;
}
//check for empty
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
writepos = rb->writepos;
}
if(rb->readpos == writepos){
return(-1);
}
value = *(rb->readpos);
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
rb->readpos = next;
}
return(value);
}

@ -0,0 +1,12 @@
#include <stdint.h>
typedef struct {
char* startptr;
char* endptr; // points beyond last element
char* readpos;
char* writepos;
} ringbuf_t;
void ringbuf_init(ringbuf_t* rb, char* buf, int size);
Loading…
Cancel
Save