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