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