1 /*
2 * Copyright (c) 2015 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
8 #define ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
9
10 #include <zephyr/sys/util.h>
11 #include <errno.h>
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 /**
18 * @file
19 * @defgroup ring_buffer_apis Ring Buffer APIs
20 * @ingroup datastructure_apis
21 *
22 * @brief Simple ring buffer implementation.
23 *
24 * @{
25 */
26
27 /** @cond INTERNAL_HIDDEN */
28
29 /* The limit is used by algorithm for distinguishing between empty and full
30 * state.
31 */
32 #ifdef CONFIG_RING_BUFFER_LARGE
33 typedef uint32_t ring_buf_idx_t;
34 #define RING_BUFFER_MAX_SIZE (UINT32_MAX / 2)
35 #define RING_BUFFER_SIZE_ASSERT_MSG "Size too big"
36 #else
37 typedef uint16_t ring_buf_idx_t;
38 #define RING_BUFFER_MAX_SIZE (UINT16_MAX / 2)
39 #define RING_BUFFER_SIZE_ASSERT_MSG "Size too big, please enable CONFIG_RING_BUFFER_LARGE"
40 #endif
41
42
43 struct ring_buf_index { ring_buf_idx_t head, tail, base; };
44
45 /** @endcond */
46
47 /**
48 * @brief A structure to represent a ring buffer
49 */
50 struct ring_buf {
51 /** @cond INTERNAL_HIDDEN */
52 uint8_t *buffer;
53 struct ring_buf_index put;
54 struct ring_buf_index get;
55 uint32_t size;
56 /** @endcond */
57 };
58
59 /** @cond INTERNAL_HIDDEN */
60
61 uint32_t ring_buf_area_claim(struct ring_buf *buf, struct ring_buf_index *ring,
62 uint8_t **data, uint32_t size);
63 int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring,
64 uint32_t size);
65
66 /**
67 * @brief Function to force ring_buf internal states to given value
68 *
69 * Any value other than 0 makes sense only in validation testing context.
70 */
ring_buf_internal_reset(struct ring_buf * buf,ring_buf_idx_t value)71 static inline void ring_buf_internal_reset(struct ring_buf *buf, ring_buf_idx_t value)
72 {
73 buf->put.head = buf->put.tail = buf->put.base = value;
74 buf->get.head = buf->get.tail = buf->get.base = value;
75 }
76
77 /** @endcond */
78
79 #define RING_BUF_INIT(buf, size8) \
80 { \
81 .buffer = buf, \
82 .size = size8, \
83 }
84
85 /**
86 * @brief Define and initialize a ring buffer for byte data.
87 *
88 * This macro establishes a ring buffer of an arbitrary size.
89 * The basic storage unit is a byte.
90 *
91 * The ring buffer can be accessed outside the module where it is defined
92 * using:
93 *
94 * @code extern struct ring_buf <name>; @endcode
95 *
96 * @param name Name of the ring buffer.
97 * @param size8 Size of ring buffer (in bytes).
98 */
99 #define RING_BUF_DECLARE(name, size8) \
100 BUILD_ASSERT(size8 <= RING_BUFFER_MAX_SIZE,\
101 RING_BUFFER_SIZE_ASSERT_MSG); \
102 static uint8_t __noinit _ring_buffer_data_##name[size8]; \
103 struct ring_buf name = RING_BUF_INIT(_ring_buffer_data_##name, size8)
104
105 /**
106 * @brief Define and initialize an "item based" ring buffer.
107 *
108 * This macro establishes an "item based" ring buffer. Each data item is
109 * an array of 32-bit words (from zero to 1020 bytes in length), coupled
110 * with a 16-bit type identifier and an 8-bit integer value.
111 *
112 * The ring buffer can be accessed outside the module where it is defined
113 * using:
114 *
115 * @code extern struct ring_buf <name>; @endcode
116 *
117 * @param name Name of the ring buffer.
118 * @param size32 Size of ring buffer (in 32-bit words).
119 */
120 #define RING_BUF_ITEM_DECLARE(name, size32) \
121 BUILD_ASSERT((size32) <= RING_BUFFER_MAX_SIZE / 4, \
122 RING_BUFFER_SIZE_ASSERT_MSG); \
123 static uint32_t __noinit _ring_buffer_data_##name[size32]; \
124 struct ring_buf name = { \
125 .buffer = (uint8_t *) _ring_buffer_data_##name, \
126 .size = 4 * (size32) \
127 }
128
129 /**
130 * @brief Define and initialize an "item based" ring buffer.
131 *
132 * This exists for backward compatibility reasons. @ref RING_BUF_ITEM_DECLARE
133 * should be used instead.
134 *
135 * @param name Name of the ring buffer.
136 * @param size32 Size of ring buffer (in 32-bit words).
137 */
138 #define RING_BUF_ITEM_DECLARE_SIZE(name, size32) \
139 RING_BUF_ITEM_DECLARE(name, size32)
140
141 /**
142 * @brief Define and initialize a power-of-2 sized "item based" ring buffer.
143 *
144 * This macro establishes an "item based" ring buffer by specifying its
145 * size using a power of 2. This exists mainly for backward compatibility
146 * reasons. @ref RING_BUF_ITEM_DECLARE should be used instead.
147 *
148 * @param name Name of the ring buffer.
149 * @param pow Ring buffer size exponent.
150 */
151 #define RING_BUF_ITEM_DECLARE_POW2(name, pow) \
152 RING_BUF_ITEM_DECLARE(name, BIT(pow))
153
154 /**
155 * @brief Compute the ring buffer size in 32-bit needed to store an element
156 *
157 * The argument can be a type or an expression.
158 * Note: rounds up if the size is not a multiple of 32 bits.
159 *
160 * @param expr Expression or type to compute the size of
161 */
162 #define RING_BUF_ITEM_SIZEOF(expr) DIV_ROUND_UP(sizeof(expr), sizeof(uint32_t))
163
164 /**
165 * @brief Initialize a ring buffer for byte data.
166 *
167 * This routine initializes a ring buffer, prior to its first use. It is only
168 * used for ring buffers not defined using RING_BUF_DECLARE.
169 *
170 * @param buf Address of ring buffer.
171 * @param size Ring buffer size (in bytes).
172 * @param data Ring buffer data area (uint8_t data[size]).
173 */
ring_buf_init(struct ring_buf * buf,uint32_t size,uint8_t * data)174 static inline void ring_buf_init(struct ring_buf *buf,
175 uint32_t size,
176 uint8_t *data)
177 {
178 __ASSERT(size <= RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
179
180 buf->size = size;
181 buf->buffer = data;
182 ring_buf_internal_reset(buf, 0);
183 }
184
185 /**
186 * @brief Initialize an "item based" ring buffer.
187 *
188 * This routine initializes a ring buffer, prior to its first use. It is only
189 * used for ring buffers not defined using RING_BUF_ITEM_DECLARE.
190 *
191 * Each data item is an array of 32-bit words (from zero to 1020 bytes in
192 * length), coupled with a 16-bit type identifier and an 8-bit integer value.
193 *
194 * @param buf Address of ring buffer.
195 * @param size Ring buffer size (in 32-bit words)
196 * @param data Ring buffer data area (uint32_t data[size]).
197 */
ring_buf_item_init(struct ring_buf * buf,uint32_t size,uint32_t * data)198 static inline void ring_buf_item_init(struct ring_buf *buf,
199 uint32_t size,
200 uint32_t *data)
201 {
202 __ASSERT(size <= RING_BUFFER_MAX_SIZE / 4, RING_BUFFER_SIZE_ASSERT_MSG);
203 ring_buf_init(buf, 4 * size, (uint8_t *)data);
204 }
205
206 /**
207 * @brief Determine if a ring buffer is empty.
208 *
209 * @param buf Address of ring buffer.
210 *
211 * @return true if the ring buffer is empty, or false if not.
212 */
ring_buf_is_empty(const struct ring_buf * buf)213 static inline bool ring_buf_is_empty(const struct ring_buf *buf)
214 {
215 return buf->get.head == buf->put.tail;
216 }
217
218 /**
219 * @brief Reset ring buffer state.
220 *
221 * @param buf Address of ring buffer.
222 */
ring_buf_reset(struct ring_buf * buf)223 static inline void ring_buf_reset(struct ring_buf *buf)
224 {
225 ring_buf_internal_reset(buf, 0);
226 }
227
228 /**
229 * @brief Determine free space in a ring buffer.
230 *
231 * @param buf Address of ring buffer.
232 *
233 * @return Ring buffer free space (in bytes).
234 */
ring_buf_space_get(const struct ring_buf * buf)235 static inline uint32_t ring_buf_space_get(const struct ring_buf *buf)
236 {
237 ring_buf_idx_t allocated = buf->put.head - buf->get.tail;
238
239 return buf->size - allocated;
240 }
241
242 /**
243 * @brief Determine free space in an "item based" ring buffer.
244 *
245 * @param buf Address of ring buffer.
246 *
247 * @return Ring buffer free space (in 32-bit words).
248 */
ring_buf_item_space_get(const struct ring_buf * buf)249 static inline uint32_t ring_buf_item_space_get(const struct ring_buf *buf)
250 {
251 return ring_buf_space_get(buf) / 4;
252 }
253
254 /**
255 * @brief Return ring buffer capacity.
256 *
257 * @param buf Address of ring buffer.
258 *
259 * @return Ring buffer capacity (in bytes).
260 */
ring_buf_capacity_get(const struct ring_buf * buf)261 static inline uint32_t ring_buf_capacity_get(const struct ring_buf *buf)
262 {
263 return buf->size;
264 }
265
266 /**
267 * @brief Determine size of available data in a ring buffer.
268 *
269 * @param buf Address of ring buffer.
270 *
271 * @return Ring buffer data size (in bytes).
272 */
ring_buf_size_get(const struct ring_buf * buf)273 static inline uint32_t ring_buf_size_get(const struct ring_buf *buf)
274 {
275 ring_buf_idx_t available = buf->put.tail - buf->get.head;
276
277 return available;
278 }
279
280 /**
281 * @brief Allocate buffer for writing data to a ring buffer.
282 *
283 * With this routine, memory copying can be reduced since internal ring buffer
284 * can be used directly by the user. Once data is written to allocated area
285 * number of bytes written must be confirmed (see @ref ring_buf_put_finish).
286 *
287 * @warning
288 * Use cases involving multiple writers to the ring buffer must prevent
289 * concurrent write operations, either by preventing all writers from
290 * being preempted or by using a mutex to govern writes to the ring buffer.
291 *
292 * @warning
293 * Ring buffer instance should not mix byte access and item access
294 * (calls prefixed with ring_buf_item_).
295 *
296 * @param[in] buf Address of ring buffer.
297 * @param[out] data Pointer to the address. It is set to a location within
298 * ring buffer.
299 * @param[in] size Requested allocation size (in bytes).
300 *
301 * @return Size of allocated buffer which can be smaller than requested if
302 * there is not enough free space or buffer wraps.
303 */
ring_buf_put_claim(struct ring_buf * buf,uint8_t ** data,uint32_t size)304 static inline uint32_t ring_buf_put_claim(struct ring_buf *buf,
305 uint8_t **data,
306 uint32_t size)
307 {
308 uint32_t space = ring_buf_space_get(buf);
309 return ring_buf_area_claim(buf, &buf->put, data,
310 MIN(size, space));
311 }
312
313 /**
314 * @brief Indicate number of bytes written to allocated buffers.
315 *
316 * The number of bytes must be equal to or lower than the sum corresponding
317 * to all preceding @ref ring_buf_put_claim invocations (or even 0). Surplus
318 * bytes will be returned to the available free buffer space.
319 *
320 * @warning
321 * Use cases involving multiple writers to the ring buffer must prevent
322 * concurrent write operations, either by preventing all writers from
323 * being preempted or by using a mutex to govern writes to the ring buffer.
324 *
325 * @warning
326 * Ring buffer instance should not mix byte access and item access
327 * (calls prefixed with ring_buf_item_).
328 *
329 * @param buf Address of ring buffer.
330 * @param size Number of valid bytes in the allocated buffers.
331 *
332 * @retval 0 Successful operation.
333 * @retval -EINVAL Provided @a size exceeds free space in the ring buffer.
334 */
ring_buf_put_finish(struct ring_buf * buf,uint32_t size)335 static inline int ring_buf_put_finish(struct ring_buf *buf, uint32_t size)
336 {
337 return ring_buf_area_finish(buf, &buf->put, size);
338 }
339
340 /**
341 * @brief Write (copy) data to a ring buffer.
342 *
343 * This routine writes data to a ring buffer @a buf.
344 *
345 * @warning
346 * Use cases involving multiple writers to the ring buffer must prevent
347 * concurrent write operations, either by preventing all writers from
348 * being preempted or by using a mutex to govern writes to the ring buffer.
349 *
350 * @warning
351 * Ring buffer instance should not mix byte access and item access
352 * (calls prefixed with ring_buf_item_).
353 *
354 * @param buf Address of ring buffer.
355 * @param data Address of data.
356 * @param size Data size (in bytes).
357 *
358 * @return Number of bytes written.
359 */
360 uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size);
361
362 /**
363 * @brief Get address of a valid data in a ring buffer.
364 *
365 * With this routine, memory copying can be reduced since internal ring buffer
366 * can be used directly by the user. Once data is processed it must be freed
367 * using @ref ring_buf_get_finish.
368 *
369 * @warning
370 * Use cases involving multiple reads of the ring buffer must prevent
371 * concurrent read operations, either by preventing all readers from
372 * being preempted or by using a mutex to govern reads to the ring buffer.
373 *
374 * @warning
375 * Ring buffer instance should not mix byte access and item access
376 * (calls prefixed with ring_buf_item_).
377 *
378 * @param[in] buf Address of ring buffer.
379 * @param[out] data Pointer to the address. It is set to a location within
380 * ring buffer.
381 * @param[in] size Requested size (in bytes).
382 *
383 * @return Number of valid bytes in the provided buffer which can be smaller
384 * than requested if there is not enough free space or buffer wraps.
385 */
ring_buf_get_claim(struct ring_buf * buf,uint8_t ** data,uint32_t size)386 static inline uint32_t ring_buf_get_claim(struct ring_buf *buf,
387 uint8_t **data,
388 uint32_t size)
389 {
390 uint32_t buf_size = ring_buf_size_get(buf);
391 return ring_buf_area_claim(buf, &buf->get, data,
392 MIN(size, buf_size));
393 }
394
395 /**
396 * @brief Indicate number of bytes read from claimed buffer.
397 *
398 * The number of bytes must be equal or lower than the sum corresponding to
399 * all preceding @ref ring_buf_get_claim invocations (or even 0). Surplus
400 * bytes will remain available in the buffer.
401 *
402 * @warning
403 * Use cases involving multiple reads of the ring buffer must prevent
404 * concurrent read operations, either by preventing all readers from
405 * being preempted or by using a mutex to govern reads to the ring buffer.
406 *
407 * @warning
408 * Ring buffer instance should not mix byte access and item mode
409 * (calls prefixed with ring_buf_item_).
410 *
411 * @param buf Address of ring buffer.
412 * @param size Number of bytes that can be freed.
413 *
414 * @retval 0 Successful operation.
415 * @retval -EINVAL Provided @a size exceeds valid bytes in the ring buffer.
416 */
ring_buf_get_finish(struct ring_buf * buf,uint32_t size)417 static inline int ring_buf_get_finish(struct ring_buf *buf, uint32_t size)
418 {
419 return ring_buf_area_finish(buf, &buf->get, size);
420 }
421
422 /**
423 * @brief Read data from a ring buffer.
424 *
425 * This routine reads data from a ring buffer @a buf.
426 *
427 * @warning
428 * Use cases involving multiple reads of the ring buffer must prevent
429 * concurrent read operations, either by preventing all readers from
430 * being preempted or by using a mutex to govern reads to the ring buffer.
431 *
432 * @warning
433 * Ring buffer instance should not mix byte access and item mode
434 * (calls prefixed with ring_buf_item_).
435 *
436 * @param buf Address of ring buffer.
437 * @param data Address of the output buffer. Can be NULL to discard data.
438 * @param size Data size (in bytes).
439 *
440 * @return Number of bytes written to the output buffer.
441 */
442 uint32_t ring_buf_get(struct ring_buf *buf, uint8_t *data, uint32_t size);
443
444 /**
445 * @brief Peek at data from a ring buffer.
446 *
447 * This routine reads data from a ring buffer @a buf without removal.
448 *
449 * @warning
450 * Use cases involving multiple reads of the ring buffer must prevent
451 * concurrent read operations, either by preventing all readers from
452 * being preempted or by using a mutex to govern reads to the ring buffer.
453 *
454 * @warning
455 * Ring buffer instance should not mix byte access and item mode
456 * (calls prefixed with ring_buf_item_).
457 *
458 * @warning
459 * Multiple calls to peek will result in the same data being 'peeked'
460 * multiple times. To remove data, use either @ref ring_buf_get or
461 * @ref ring_buf_get_claim followed by @ref ring_buf_get_finish with a
462 * non-zero `size`.
463 *
464 * @param buf Address of ring buffer.
465 * @param data Address of the output buffer. Cannot be NULL.
466 * @param size Data size (in bytes).
467 *
468 * @return Number of bytes written to the output buffer.
469 */
470 uint32_t ring_buf_peek(struct ring_buf *buf, uint8_t *data, uint32_t size);
471
472 /**
473 * @brief Write a data item to a ring buffer.
474 *
475 * This routine writes a data item to ring buffer @a buf. The data item
476 * is an array of 32-bit words (from zero to 1020 bytes in length),
477 * coupled with a 16-bit type identifier and an 8-bit integer value.
478 *
479 * @warning
480 * Use cases involving multiple writers to the ring buffer must prevent
481 * concurrent write operations, either by preventing all writers from
482 * being preempted or by using a mutex to govern writes to the ring buffer.
483 *
484 * @param buf Address of ring buffer.
485 * @param type Data item's type identifier (application specific).
486 * @param value Data item's integer value (application specific).
487 * @param data Address of data item.
488 * @param size32 Data item size (number of 32-bit words).
489 *
490 * @retval 0 Data item was written.
491 * @retval -EMSGSIZE Ring buffer has insufficient free space.
492 */
493 int ring_buf_item_put(struct ring_buf *buf, uint16_t type, uint8_t value,
494 uint32_t *data, uint8_t size32);
495
496 /**
497 * @brief Read a data item from a ring buffer.
498 *
499 * This routine reads a data item from ring buffer @a buf. The data item
500 * is an array of 32-bit words (up to 1020 bytes in length),
501 * coupled with a 16-bit type identifier and an 8-bit integer value.
502 *
503 * @warning
504 * Use cases involving multiple reads of the ring buffer must prevent
505 * concurrent read operations, either by preventing all readers from
506 * being preempted or by using a mutex to govern reads to the ring buffer.
507 *
508 * @param buf Address of ring buffer.
509 * @param type Area to store the data item's type identifier.
510 * @param value Area to store the data item's integer value.
511 * @param data Area to store the data item. Can be NULL to discard data.
512 * @param size32 Size of the data item storage area (number of 32-bit chunks).
513 *
514 * @retval 0 Data item was fetched; @a size32 now contains the number of
515 * 32-bit words read into data area @a data.
516 * @retval -EAGAIN Ring buffer is empty.
517 * @retval -EMSGSIZE Data area @a data is too small; @a size32 now contains
518 * the number of 32-bit words needed.
519 */
520 int ring_buf_item_get(struct ring_buf *buf, uint16_t *type, uint8_t *value,
521 uint32_t *data, uint8_t *size32);
522
523 /**
524 * @}
525 */
526
527 #ifdef __cplusplus
528 }
529 #endif
530
531 #endif /* ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_ */
532