parent
cdbac9c8a5
commit
2aaeee4e55
@ -0,0 +1,67 @@
|
||||
#include "ringbuf_small.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->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;
|
||||
char* readpos;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
#include <stdint.h>
|
||||
|
||||
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);
|
||||
|
||||
Loading…
Reference in new issue