--- /dev/null
+#ifndef RINGBUFFER_H_
+#define RINGBUFFER_H_
+
+#define RINGBUFFER(name, size) uint8_t name[(size)+4] = { size, 0, 0, 0 }
+
+static inline uint8_t ringbuffer_fill(const uint8_t *buffer)
+{
+ return buffer[1];
+}
+
+static inline uint8_t ringbuffer_space(const uint8_t *buffer)
+{
+ return buffer[0]-buffer[1];
+}
+
+static inline void ringbuffer_push(uint8_t *buffer, uint8_t value)
+{
+ const uint8_t size = buffer[0];
+ uint8_t head = buffer[2];
+ buffer[4+head++] = value;
+ if(head>=size)
+ head -= size;
+ buffer[2] = head;
+ ++buffer[1];
+}
+
+static inline void ringbuffer_blocking_push(uint8_t *buffer, uint8_t value)
+{
+ const volatile uint8_t *fill = buffer+1;
+ while(*fill>=buffer[0]) ;
+ ringbuffer_push(buffer, value);
+}
+
+static inline uint8_t ringbuffer_pop(uint8_t *buffer)
+{
+ const uint8_t size = buffer[0];
+ uint8_t tail = buffer[3];
+ uint8_t value = buffer[4+tail++];
+ if(tail>=size)
+ tail -= size;
+ buffer[3] = tail;
+ --buffer[1];
+ return value;
+}
+
+static inline uint8_t rinbuffer_blocking_pop(uint8_t *buffer)
+{
+ const volatile uint8_t *fill = buffer+1;
+ while(*fill==0) ;
+ return ringbuffer_pop(buffer);
+}
+
+#endif