Line data Source code
1 0 : /*
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 1 : 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 : */
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 0 : #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 1 : #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 1 : #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 1 : #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 1 : #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 1 : #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 : */
173 1 : 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 : */
197 1 : 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 : */
212 1 : 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 : */
222 1 : 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 : */
234 1 : 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 : */
248 1 : 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 : */
260 1 : 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 : */
272 1 : 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 : */
303 1 : static inline uint32_t ring_buf_put_claim(struct ring_buf *buf,
304 : uint8_t **data,
305 : uint32_t size)
306 : {
307 : uint32_t space = ring_buf_space_get(buf);
308 : return ring_buf_area_claim(buf, &buf->put, data,
309 : MIN(size, space));
310 : }
311 :
312 : /**
313 : * @brief Indicate number of bytes written to allocated buffers.
314 : *
315 : * The number of bytes must be equal to or lower than the sum corresponding
316 : * to all preceding @ref ring_buf_put_claim invocations (or even 0). Surplus
317 : * bytes will be returned to the available free buffer space.
318 : *
319 : * @warning
320 : * Use cases involving multiple writers to the ring buffer must prevent
321 : * concurrent write operations, either by preventing all writers from
322 : * being preempted or by using a mutex to govern writes to the ring buffer.
323 : *
324 : * @warning
325 : * Ring buffer instance should not mix byte access and item access
326 : * (calls prefixed with ring_buf_item_).
327 : *
328 : * @param buf Address of ring buffer.
329 : * @param size Number of valid bytes in the allocated buffers.
330 : *
331 : * @retval 0 Successful operation.
332 : * @retval -EINVAL Provided @a size exceeds free space in the ring buffer.
333 : */
334 1 : static inline int ring_buf_put_finish(struct ring_buf *buf, uint32_t size)
335 : {
336 : return ring_buf_area_finish(buf, &buf->put, size);
337 : }
338 :
339 : /**
340 : * @brief Write (copy) data to a ring buffer.
341 : *
342 : * This routine writes data to a ring buffer @a buf.
343 : *
344 : * @warning
345 : * Use cases involving multiple writers to the ring buffer must prevent
346 : * concurrent write operations, either by preventing all writers from
347 : * being preempted or by using a mutex to govern writes to the ring buffer.
348 : *
349 : * @warning
350 : * Ring buffer instance should not mix byte access and item access
351 : * (calls prefixed with ring_buf_item_).
352 : *
353 : * @param buf Address of ring buffer.
354 : * @param data Address of data.
355 : * @param size Data size (in bytes).
356 : *
357 : * @retval Number of bytes written.
358 : */
359 1 : uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size);
360 :
361 : /**
362 : * @brief Get address of a valid data in a ring buffer.
363 : *
364 : * With this routine, memory copying can be reduced since internal ring buffer
365 : * can be used directly by the user. Once data is processed it must be freed
366 : * using @ref ring_buf_get_finish.
367 : *
368 : * @warning
369 : * Use cases involving multiple reads of the ring buffer must prevent
370 : * concurrent read operations, either by preventing all readers from
371 : * being preempted or by using a mutex to govern reads to the ring buffer.
372 : *
373 : * @warning
374 : * Ring buffer instance should not mix byte access and item access
375 : * (calls prefixed with ring_buf_item_).
376 : *
377 : * @param[in] buf Address of ring buffer.
378 : * @param[out] data Pointer to the address. It is set to a location within
379 : * ring buffer.
380 : * @param[in] size Requested size (in bytes).
381 : *
382 : * @return Number of valid bytes in the provided buffer which can be smaller
383 : * than requested if there is not enough free space or buffer wraps.
384 : */
385 1 : static inline uint32_t ring_buf_get_claim(struct ring_buf *buf,
386 : uint8_t **data,
387 : uint32_t size)
388 : {
389 : uint32_t buf_size = ring_buf_size_get(buf);
390 : return ring_buf_area_claim(buf, &buf->get, data,
391 : MIN(size, buf_size));
392 : }
393 :
394 : /**
395 : * @brief Indicate number of bytes read from claimed buffer.
396 : *
397 : * The number of bytes must be equal or lower than the sum corresponding to
398 : * all preceding @ref ring_buf_get_claim invocations (or even 0). Surplus
399 : * bytes will remain available in the buffer.
400 : *
401 : * @warning
402 : * Use cases involving multiple reads of the ring buffer must prevent
403 : * concurrent read operations, either by preventing all readers from
404 : * being preempted or by using a mutex to govern reads to the ring buffer.
405 : *
406 : * @warning
407 : * Ring buffer instance should not mix byte access and item mode
408 : * (calls prefixed with ring_buf_item_).
409 : *
410 : * @param buf Address of ring buffer.
411 : * @param size Number of bytes that can be freed.
412 : *
413 : * @retval 0 Successful operation.
414 : * @retval -EINVAL Provided @a size exceeds valid bytes in the ring buffer.
415 : */
416 1 : static inline int ring_buf_get_finish(struct ring_buf *buf, uint32_t size)
417 : {
418 : return ring_buf_area_finish(buf, &buf->get, size);
419 : }
420 :
421 : /**
422 : * @brief Read data from a ring buffer.
423 : *
424 : * This routine reads data from a ring buffer @a buf.
425 : *
426 : * @warning
427 : * Use cases involving multiple reads of the ring buffer must prevent
428 : * concurrent read operations, either by preventing all readers from
429 : * being preempted or by using a mutex to govern reads to the ring buffer.
430 : *
431 : * @warning
432 : * Ring buffer instance should not mix byte access and item mode
433 : * (calls prefixed with ring_buf_item_).
434 : *
435 : * @param buf Address of ring buffer.
436 : * @param data Address of the output buffer. Can be NULL to discard data.
437 : * @param size Data size (in bytes).
438 : *
439 : * @retval Number of bytes written to the output buffer.
440 : */
441 1 : uint32_t ring_buf_get(struct ring_buf *buf, uint8_t *data, uint32_t size);
442 :
443 : /**
444 : * @brief Peek at data from a ring buffer.
445 : *
446 : * This routine reads data from a ring buffer @a buf without removal.
447 : *
448 : * @warning
449 : * Use cases involving multiple reads of the ring buffer must prevent
450 : * concurrent read operations, either by preventing all readers from
451 : * being preempted or by using a mutex to govern reads to the ring buffer.
452 : *
453 : * @warning
454 : * Ring buffer instance should not mix byte access and item mode
455 : * (calls prefixed with ring_buf_item_).
456 : *
457 : * @warning
458 : * Multiple calls to peek will result in the same data being 'peeked'
459 : * multiple times. To remove data, use either @ref ring_buf_get or
460 : * @ref ring_buf_get_claim followed by @ref ring_buf_get_finish with a
461 : * non-zero `size`.
462 : *
463 : * @param buf Address of ring buffer.
464 : * @param data Address of the output buffer. Cannot be NULL.
465 : * @param size Data size (in bytes).
466 : *
467 : * @retval Number of bytes written to the output buffer.
468 : */
469 1 : uint32_t ring_buf_peek(struct ring_buf *buf, uint8_t *data, uint32_t size);
470 :
471 : /**
472 : * @brief Write a data item to a ring buffer.
473 : *
474 : * This routine writes a data item to ring buffer @a buf. The data item
475 : * is an array of 32-bit words (from zero to 1020 bytes in length),
476 : * coupled with a 16-bit type identifier and an 8-bit integer value.
477 : *
478 : * @warning
479 : * Use cases involving multiple writers to the ring buffer must prevent
480 : * concurrent write operations, either by preventing all writers from
481 : * being preempted or by using a mutex to govern writes to the ring buffer.
482 : *
483 : * @param buf Address of ring buffer.
484 : * @param type Data item's type identifier (application specific).
485 : * @param value Data item's integer value (application specific).
486 : * @param data Address of data item.
487 : * @param size32 Data item size (number of 32-bit words).
488 : *
489 : * @retval 0 Data item was written.
490 : * @retval -EMSGSIZE Ring buffer has insufficient free space.
491 : */
492 1 : int ring_buf_item_put(struct ring_buf *buf, uint16_t type, uint8_t value,
493 : uint32_t *data, uint8_t size32);
494 :
495 : /**
496 : * @brief Read a data item from a ring buffer.
497 : *
498 : * This routine reads a data item from ring buffer @a buf. The data item
499 : * is an array of 32-bit words (up to 1020 bytes in length),
500 : * coupled with a 16-bit type identifier and an 8-bit integer value.
501 : *
502 : * @warning
503 : * Use cases involving multiple reads of the ring buffer must prevent
504 : * concurrent read operations, either by preventing all readers from
505 : * being preempted or by using a mutex to govern reads to the ring buffer.
506 : *
507 : * @param buf Address of ring buffer.
508 : * @param type Area to store the data item's type identifier.
509 : * @param value Area to store the data item's integer value.
510 : * @param data Area to store the data item. Can be NULL to discard data.
511 : * @param size32 Size of the data item storage area (number of 32-bit chunks).
512 : *
513 : * @retval 0 Data item was fetched; @a size32 now contains the number of
514 : * 32-bit words read into data area @a data.
515 : * @retval -EAGAIN Ring buffer is empty.
516 : * @retval -EMSGSIZE Data area @a data is too small; @a size32 now contains
517 : * the number of 32-bit words needed.
518 : */
519 1 : int ring_buf_item_get(struct ring_buf *buf, uint16_t *type, uint8_t *value,
520 : uint32_t *data, uint8_t *size32);
521 :
522 : /**
523 : * @}
524 : */
525 :
526 : #ifdef __cplusplus
527 : }
528 : #endif
529 :
530 : #endif /* ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_ */
|