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