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