1 /* ring_buffer.h: Simple ring buffer API */
2
3 /*
4 * Copyright (c) 2015 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 /** @file */
9
10 #ifndef ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
11 #define ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
12
13 #include <kernel.h>
14 #include <sys/util.h>
15 #include <errno.h>
16 #include <string.h>
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 #define SIZE32_OF(x) (sizeof((x))/sizeof(uint32_t))
23
24 /* The limit is used by algorithm for distinguishing between empty and full
25 * state.
26 */
27 #define RING_BUFFER_MAX_SIZE 0x80000000
28
29 #define RING_BUFFER_SIZE_ASSERT_MSG \
30 "Size too big, if it is the ring buffer test check custom max size"
31 /**
32 * @brief A structure to represent a ring buffer
33 */
34 struct ring_buf {
35 uint32_t head; /**< Index in buf for the head element */
36 uint32_t tail; /**< Index in buf for the tail element */
37 union ring_buf_misc {
38 struct ring_buf_misc_item_mode {
39 uint32_t dropped_put_count; /**< Running tally of the
40 * number of failed put
41 * attempts.
42 */
43 } item_mode;
44 struct ring_buf_misc_byte_mode {
45 uint32_t tmp_tail;
46 uint32_t tmp_head;
47 } byte_mode;
48 } misc;
49 uint32_t size; /**< Size of buf in 32-bit chunks */
50
51 union ring_buf_buffer {
52 uint32_t *buf32; /**< Memory region for stored entries */
53 uint8_t *buf8;
54 } buf;
55 uint32_t mask; /**< Modulo mask if size is a power of 2 */
56
57 struct k_spinlock lock;
58 };
59
60 /**
61 * @defgroup ring_buffer_apis Ring Buffer APIs
62 * @ingroup datastructure_apis
63 * @{
64 */
65
66 /**
67 * @brief Define and initialize a high performance ring buffer.
68 *
69 * This macro establishes a ring buffer whose size must be a power of 2;
70 * that is, the ring buffer contains 2^pow 32-bit words, where @a pow is
71 * the specified ring buffer size exponent. A high performance ring buffer
72 * doesn't require the use of modulo arithmetic operations to maintain itself.
73 *
74 * The ring buffer can be accessed outside the module where it is defined
75 * using:
76 *
77 * @code extern struct ring_buf <name>; @endcode
78 *
79 * @param name Name of the ring buffer.
80 * @param pow Ring buffer size exponent.
81 */
82 #define RING_BUF_ITEM_DECLARE_POW2(name, pow) \
83 BUILD_ASSERT((1 << pow) < RING_BUFFER_MAX_SIZE,\
84 RING_BUFFER_SIZE_ASSERT_MSG); \
85 static uint32_t __noinit _ring_buffer_data_##name[BIT(pow)]; \
86 struct ring_buf name = { \
87 .size = (BIT(pow)), \
88 .mask = (BIT(pow)) - 1, \
89 .buf = { .buf32 = _ring_buffer_data_##name } \
90 }
91
92 /**
93 * @brief Define and initialize a standard ring buffer.
94 *
95 * This macro establishes a ring buffer of an arbitrary size. A standard
96 * ring buffer uses modulo arithmetic operations to maintain itself.
97 *
98 * The ring buffer can be accessed outside the module where it is defined
99 * using:
100 *
101 * @code extern struct ring_buf <name>; @endcode
102 *
103 * @param name Name of the ring buffer.
104 * @param size32 Size of ring buffer (in 32-bit words).
105 */
106 #define RING_BUF_ITEM_DECLARE_SIZE(name, size32) \
107 BUILD_ASSERT(size32 < RING_BUFFER_MAX_SIZE,\
108 RING_BUFFER_SIZE_ASSERT_MSG); \
109 static uint32_t __noinit _ring_buffer_data_##name[size32]; \
110 struct ring_buf name = { \
111 .size = size32, \
112 .buf = { .buf32 = _ring_buffer_data_##name} \
113 }
114
115 /**
116 * @brief Define and initialize a ring buffer for byte data.
117 *
118 * This macro establishes a ring buffer of an arbitrary size.
119 *
120 * The ring buffer can be accessed outside the module where it is defined
121 * using:
122 *
123 * @code extern struct ring_buf <name>; @endcode
124 *
125 * @param name Name of the ring buffer.
126 * @param size8 Size of ring buffer (in bytes).
127 */
128 #define RING_BUF_DECLARE(name, size8) \
129 BUILD_ASSERT(size8 < RING_BUFFER_MAX_SIZE,\
130 RING_BUFFER_SIZE_ASSERT_MSG); \
131 static uint8_t __noinit _ring_buffer_data_##name[size8]; \
132 struct ring_buf name = { \
133 .size = size8, \
134 .buf = { .buf8 = _ring_buffer_data_##name} \
135 }
136
137
138 /**
139 * @brief Initialize a ring buffer.
140 *
141 * This routine initializes a ring buffer, prior to its first use. It is only
142 * used for ring buffers not defined using RING_BUF_DECLARE,
143 * RING_BUF_ITEM_DECLARE_POW2 or RING_BUF_ITEM_DECLARE_SIZE.
144 *
145 * Setting @a size to a power of 2 establishes a high performance ring buffer
146 * that doesn't require the use of modulo arithmetic operations to maintain
147 * itself.
148 *
149 * @param buf Address of ring buffer.
150 * @param size Ring buffer size (in 32-bit words or bytes).
151 * @param data Ring buffer data area (uint32_t data[size] or uint8_t data[size]
152 * for bytes mode).
153 */
ring_buf_init(struct ring_buf * buf,uint32_t size,void * data)154 static inline void ring_buf_init(struct ring_buf *buf,
155 uint32_t size,
156 void *data)
157 {
158 __ASSERT(size < RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
159
160 memset(buf, 0, sizeof(struct ring_buf));
161 buf->size = size;
162 buf->buf.buf32 = (uint32_t *)data;
163 if (is_power_of_two(size)) {
164 buf->mask = size - 1U;
165 } else {
166 buf->mask = 0U;
167 }
168 }
169
170 /**
171 * @brief Determine if a ring buffer is empty.
172 *
173 * @param buf Address of ring buffer.
174 *
175 * @return 1 if the ring buffer is empty, or 0 if not.
176 */
177 int ring_buf_is_empty(struct ring_buf *buf);
178
179 /**
180 * @brief Reset ring buffer state.
181 *
182 * @param buf Address of ring buffer.
183 */
ring_buf_reset(struct ring_buf * buf)184 static inline void ring_buf_reset(struct ring_buf *buf)
185 {
186 buf->head = 0;
187 buf->tail = 0;
188 memset(&buf->misc, 0, sizeof(buf->misc));
189 }
190
191 /**
192 * @brief Determine free space in a ring buffer.
193 *
194 * @param buf Address of ring buffer.
195 *
196 * @return Ring buffer free space (in 32-bit words or bytes).
197 */
198 uint32_t ring_buf_space_get(struct ring_buf *buf);
199
200 /**
201 * @brief Return ring buffer capacity.
202 *
203 * @param buf Address of ring buffer.
204 *
205 * @return Ring buffer capacity (in 32-bit words or bytes).
206 */
ring_buf_capacity_get(struct ring_buf * buf)207 static inline uint32_t ring_buf_capacity_get(struct ring_buf *buf)
208 {
209 return buf->size;
210 }
211
212 /**
213 * @brief Determine used space in a ring buffer.
214 *
215 * @param buf Address of ring buffer.
216 *
217 * @return Ring buffer space used (in 32-bit words or bytes).
218 */
219 uint32_t ring_buf_size_get(struct ring_buf *buf);
220
221 /**
222 * @brief Write a data item to a ring buffer.
223 *
224 * This routine writes a data item to ring buffer @a buf. The data item
225 * is an array of 32-bit words (from zero to 1020 bytes in length),
226 * coupled with a 16-bit type identifier and an 8-bit integer value.
227 *
228 * @warning
229 * Use cases involving multiple writers to the ring buffer must prevent
230 * concurrent write operations, either by preventing all writers from
231 * being preempted or by using a mutex to govern writes to the ring buffer.
232 *
233 * @param buf Address of ring buffer.
234 * @param type Data item's type identifier (application specific).
235 * @param value Data item's integer value (application specific).
236 * @param data Address of data item.
237 * @param size32 Data item size (number of 32-bit words).
238 *
239 * @retval 0 Data item was written.
240 * @retval -EMSGSIZE Ring buffer has insufficient free space.
241 */
242 int ring_buf_item_put(struct ring_buf *buf, uint16_t type, uint8_t value,
243 uint32_t *data, uint8_t size32);
244
245 /**
246 * @brief Read a data item from a ring buffer.
247 *
248 * This routine reads a data item from ring buffer @a buf. The data item
249 * is an array of 32-bit words (up to 1020 bytes in length),
250 * coupled with a 16-bit type identifier and an 8-bit integer value.
251 *
252 * @warning
253 * Use cases involving multiple reads of the ring buffer must prevent
254 * concurrent read operations, either by preventing all readers from
255 * being preempted or by using a mutex to govern reads to the ring buffer.
256 *
257 * @param buf Address of ring buffer.
258 * @param type Area to store the data item's type identifier.
259 * @param value Area to store the data item's integer value.
260 * @param data Area to store the data item. Can be NULL to discard data.
261 * @param size32 Size of the data item storage area (number of 32-bit chunks).
262 *
263 * @retval 0 Data item was fetched; @a size32 now contains the number of
264 * 32-bit words read into data area @a data.
265 * @retval -EAGAIN Ring buffer is empty.
266 * @retval -EMSGSIZE Data area @a data is too small; @a size32 now contains
267 * the number of 32-bit words needed.
268 */
269 int ring_buf_item_get(struct ring_buf *buf, uint16_t *type, uint8_t *value,
270 uint32_t *data, uint8_t *size32);
271
272 /**
273 * @brief Allocate buffer for writing data to a ring buffer.
274 *
275 * With this routine, memory copying can be reduced since internal ring buffer
276 * can be used directly by the user. Once data is written to allocated area
277 * number of bytes written can be confirmed (see @ref ring_buf_put_finish).
278 *
279 * @warning
280 * Use cases involving multiple writers to the ring buffer must prevent
281 * concurrent write operations, either by preventing all writers from
282 * being preempted or by using a mutex to govern writes to the ring buffer.
283 *
284 * @warning
285 * Ring buffer instance should not mix byte access and item access
286 * (calls prefixed with ring_buf_item_).
287 *
288 * @param[in] buf Address of ring buffer.
289 * @param[out] data Pointer to the address. It is set to a location within
290 * ring buffer.
291 * @param[in] size Requested allocation size (in bytes).
292 *
293 * @return Size of allocated buffer which can be smaller than requested if
294 * there is not enough free space or buffer wraps.
295 */
296 uint32_t ring_buf_put_claim(struct ring_buf *buf,
297 uint8_t **data,
298 uint32_t size);
299
300 /**
301 * @brief Indicate number of bytes written to allocated buffers.
302 *
303 * @warning
304 * Use cases involving multiple writers to the ring buffer must prevent
305 * concurrent write operations, either by preventing all writers from
306 * being preempted or by using a mutex to govern writes to the ring buffer.
307 *
308 * @warning
309 * Ring buffer instance should not mix byte access and item access
310 * (calls prefixed with ring_buf_item_).
311 *
312 * @param buf Address of ring buffer.
313 * @param size Number of valid bytes in the allocated buffers.
314 *
315 * @retval 0 Successful operation.
316 * @retval -EINVAL Provided @a size exceeds free space in the ring buffer.
317 */
318 int ring_buf_put_finish(struct ring_buf *buf, uint32_t size);
319
320 /**
321 * @brief Write (copy) data to a ring buffer.
322 *
323 * This routine writes data to a ring buffer @a buf.
324 *
325 * @warning
326 * Use cases involving multiple writers to the ring buffer must prevent
327 * concurrent write operations, either by preventing all writers from
328 * being preempted or by using a mutex to govern writes to the ring buffer.
329 *
330 * @warning
331 * Ring buffer instance should not mix byte access and item access
332 * (calls prefixed with ring_buf_item_).
333 *
334 * @param buf Address of ring buffer.
335 * @param data Address of data.
336 * @param size Data size (in bytes).
337 *
338 * @retval Number of bytes written.
339 */
340 uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size);
341
342 /**
343 * @brief Get address of a valid data in a ring buffer.
344 *
345 * With this routine, memory copying can be reduced since internal ring buffer
346 * can be used directly by the user. Once data is processed it can be freed
347 * using @ref ring_buf_get_finish.
348 *
349 * @warning
350 * Use cases involving multiple reads of the ring buffer must prevent
351 * concurrent read operations, either by preventing all readers from
352 * being preempted or by using a mutex to govern reads to the ring buffer.
353 *
354 * @warning
355 * Ring buffer instance should not mix byte access and item access
356 * (calls prefixed with ring_buf_item_).
357 *
358 * @param[in] buf Address of ring buffer.
359 * @param[out] data Pointer to the address. It is set to a location within
360 * ring buffer.
361 * @param[in] size Requested size (in bytes).
362 *
363 * @return Number of valid bytes in the provided buffer which can be smaller
364 * than requested if there is not enough free space or buffer wraps.
365 */
366 uint32_t ring_buf_get_claim(struct ring_buf *buf,
367 uint8_t **data,
368 uint32_t size);
369
370 /**
371 * @brief Indicate number of bytes read from claimed buffer.
372 *
373 * @warning
374 * Use cases involving multiple reads of the ring buffer must prevent
375 * concurrent read operations, either by preventing all readers from
376 * being preempted or by using a mutex to govern reads to the ring buffer.
377 *
378 * @warning
379 * Ring buffer instance should not mix byte access and item mode
380 * (calls prefixed with ring_buf_item_).
381 *
382 * @param buf Address of ring buffer.
383 * @param size Number of bytes that can be freed.
384 *
385 * @retval 0 Successful operation.
386 * @retval -EINVAL Provided @a size exceeds valid bytes in the ring buffer.
387 */
388 int ring_buf_get_finish(struct ring_buf *buf, uint32_t size);
389
390 /**
391 * @brief Read data from a ring buffer.
392 *
393 * This routine reads data from a ring buffer @a buf.
394 *
395 * @warning
396 * Use cases involving multiple reads of the ring buffer must prevent
397 * concurrent read operations, either by preventing all readers from
398 * being preempted or by using a mutex to govern reads to the ring buffer.
399 *
400 * @warning
401 * Ring buffer instance should not mix byte access and item mode
402 * (calls prefixed with ring_buf_item_).
403 *
404 * @param buf Address of ring buffer.
405 * @param data Address of the output buffer. Can be NULL to discard data.
406 * @param size Data size (in bytes).
407 *
408 * @retval Number of bytes written to the output buffer.
409 */
410 uint32_t ring_buf_get(struct ring_buf *buf, uint8_t *data, uint32_t size);
411
412 /**
413 * @brief Peek at data from a ring buffer.
414 *
415 * This routine reads data from a ring buffer @a buf without removal.
416 *
417 * @warning
418 * Use cases involving multiple reads of the ring buffer must prevent
419 * concurrent read operations, either by preventing all readers from
420 * being preempted or by using a mutex to govern reads to the ring buffer.
421 *
422 * @warning
423 * Ring buffer instance should not mix byte access and item mode
424 * (calls prefixed with ring_buf_item_).
425 *
426 * @warning
427 * Multiple calls to peek will result in the same data being 'peeked'
428 * multiple times. To remove data, use either @ref ring_buf_get or
429 * @ref ring_buf_get_claim followed by @ref ring_buf_get_finish with a
430 * non-zero `size`.
431 *
432 * @param buf Address of ring buffer.
433 * @param data Address of the output buffer. Cannot be NULL.
434 * @param size Data size (in bytes).
435 *
436 * @retval Number of bytes written to the output buffer.
437 */
438 uint32_t ring_buf_peek(struct ring_buf *buf, uint8_t *data, uint32_t size);
439
440 /**
441 * @}
442 */
443
444 #ifdef __cplusplus
445 }
446 #endif
447
448 #endif /* ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_ */
449