APM:Libraries
ring_buffer.h
Go to the documentation of this file.
1 /******************************************************************************
2  * The MIT License
3  *
4  * Copyright (c) 2011 LeafLabs, LLC.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use, copy,
10  * modify, merge, publish, distribute, sublicense, and/or sell copies
11  * of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  *****************************************************************************/
26 
35 #ifndef _RING_BUFFER_H_
36 #define _RING_BUFFER_H_
37 
38 #include "hal_types.h"
39 
49 typedef struct ring_buffer {
50  volatile uint8_t *buf;
51  uint16_t head;
52  uint16_t tail;
53  uint16_t size;
54 } ring_buffer;
55 
56 
57 #ifdef __cplusplus
58  extern "C" {
59 #endif
60 
73 static inline void rb_init(ring_buffer *rb, uint16_t size, uint8_t *buf) {
74  rb->head = 0;
75  rb->tail = 0;
76  rb->size = size - 1;
77  rb->buf = buf;
78 }
79 
84 static inline uint16_t rb_full_count(ring_buffer *rb) {
85  uint16_t t=rb->tail;
86  uint16_t h=rb->head;
87 
88  int32_t size = t - h;
89  if (t < h) {
90  size += rb->size + 1;
91  }
92  return (uint16_t)size;
93 }
94 
99 static inline int rb_is_full(ring_buffer *rb) {
100  uint16_t t=rb->tail;
101  uint16_t h=rb->head;
102  return (t + 1 == h || (t == rb->size && h == 0) );
103 }
104 
109 static inline int rb_is_empty(ring_buffer *rb) {
110  return rb->head == rb->tail;
111 }
112 
118 static inline void rb_insert(ring_buffer *rb, uint8_t element) {
119  uint16_t t=rb->tail;
120  rb->buf[t] = element;
121  rb->tail = (t == rb->size) ? 0 : t + 1;
122 }
123 
128 static inline uint8_t rb_remove(ring_buffer *rb) {
129  uint16_t h=rb->head;
130  uint8_t ch = rb->buf[h];
131  rb->head = (h == rb->size) ? 0 : h + 1;
132  return ch;
133 }
134 
143 static inline int16_t rb_safe_remove(ring_buffer *rb) {
144  return rb_is_empty(rb) ? -1 : rb_remove(rb);
145 }
146 
154 static inline int rb_safe_insert(ring_buffer *rb, uint8_t element) {
155  if (rb_is_full(rb)) {
156  return 0;
157  }
158  rb_insert(rb, element);
159  return 1;
160 }
161 
173 static inline int rb_push_insert(ring_buffer *rb, uint8_t element) {
174  int ret = -1;
175  if (rb_is_full(rb)) {
176  ret = rb_remove(rb);
177  }
178  rb_insert(rb, element);
179  return ret;
180 }
181 
186 static inline void rb_reset(ring_buffer *rb) {
187  rb->tail = rb->head;
188 }
189 
190 #ifdef __cplusplus
191  }
192 #endif
193 
194 #endif
195 
static void rb_insert(ring_buffer *rb, uint8_t element)
Definition: ring_buffer.h:118
uint16_t tail
Definition: ring_buffer.h:52
static int rb_is_empty(ring_buffer *rb)
Returns true if and only if the ring buffer is empty.
Definition: ring_buffer.h:109
static uint16_t rb_full_count(ring_buffer *rb)
Return the number of elements stored in the ring buffer.
Definition: ring_buffer.h:84
static uint8_t rb_remove(ring_buffer *rb)
Remove and return the first item from a ring buffer.
Definition: ring_buffer.h:128
static int16_t rb_safe_remove(ring_buffer *rb)
Attempt to remove the first item from a ring buffer.
Definition: ring_buffer.h:143
static int rb_is_full(ring_buffer *rb)
Returns true if and only if the ring buffer is full.
Definition: ring_buffer.h:99
volatile uint8_t * buf
Definition: ring_buffer.h:50
struct ring_buffer ring_buffer
uint16_t size
Definition: ring_buffer.h:53
static void rb_init(ring_buffer *rb, uint16_t size, uint8_t *buf)
Definition: ring_buffer.h:73
static int rb_safe_insert(ring_buffer *rb, uint8_t element)
Attempt to insert an element into a ring buffer.
Definition: ring_buffer.h:154
uint16_t head
Definition: ring_buffer.h:51
static void rb_reset(ring_buffer *rb)
Discard all items from a ring buffer.
Definition: ring_buffer.h:186
static int rb_push_insert(ring_buffer *rb, uint8_t element)
Append an item onto the end of a non-full ring buffer.
Definition: ring_buffer.h:173