8#ifndef ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
9#define ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
38#ifdef CONFIG_RING_BUFFER_LARGE
42#define RING_BUFFER_MAX_SIZE (UINT32_MAX / 4U)
43#define RING_BUFFER_SIZE_ASSERT_MSG "Size too large"
48#define RING_BUFFER_MAX_SIZE (UINT16_MAX / 2U)
49#define RING_BUFFER_SIZE_ASSERT_MSG \
50 "Size too large, please enable CONFIG_RING_BUFFER_LARGE"
66 ring_buf_idx_t read_idx;
67 ring_buf_idx_t write_idx;
68#ifdef CONFIG_RING_BUFFER
69 ring_buf_idx_t put_claimed;
70 ring_buf_idx_t get_claimed;
83static ALWAYS_INLINE ring_buf_idx_t rb_idx_advance(
size_t value, ring_buf_size_t size)
85 size_t lim = 2U * size;
87 return (ring_buf_idx_t)(value >= lim ? value - lim : value);
90static ALWAYS_INLINE ring_buf_idx_t rb_load_acquire(
const ring_buf_idx_t *p)
94#if IS_ENABLED(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1)
95 v = __atomic_load_n(p, __ATOMIC_ACQUIRE);
103static ALWAYS_INLINE ring_buf_idx_t rb_load_relaxed(
const ring_buf_idx_t *p)
105#if IS_ENABLED(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1)
106 return __atomic_load_n(p, __ATOMIC_RELAXED);
112static ALWAYS_INLINE void rb_store_release(ring_buf_idx_t *p, ring_buf_idx_t v)
114#if IS_ENABLED(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1)
115 __atomic_store_n(p, v, __ATOMIC_RELEASE);
122static ALWAYS_INLINE void rb_store_relaxed(ring_buf_idx_t *p, ring_buf_idx_t v)
124#if IS_ENABLED(CONFIG_SMP) && (CONFIG_MP_MAX_NUM_CPUS > 1)
125 __atomic_store_n(p, v, __ATOMIC_RELAXED);
142#define RING_BUF_INIT(buf, sz) \
145 .size = (ring_buf_size_t)(sz), \
163#define RING_BUF_DECLARE(name, size8) \
164 BUILD_ASSERT((size8) <= RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG); \
165 static uint8_t __noinit _ring_buffer_data_##name[(size8)]; \
166 struct ring_buf name = RING_BUF_INIT(_ring_buffer_data_##name, (size8))
189 ring_buf_idx_t write_idx = rb_load_acquire(&rb->write_idx);
190 ring_buf_idx_t read_idx = rb_load_acquire(&rb->read_idx);
191 ring_buf_size_t occ = write_idx - read_idx;
193 if (write_idx < read_idx) {
194 occ += 2U * rb->size;
220 ring_buf_idx_t write_idx = rb_load_acquire(&rb->write_idx);
221 ring_buf_idx_t read_idx = rb_load_acquire(&rb->read_idx);
223 return write_idx == read_idx;
245 rb_store_relaxed(&rb->read_idx, 0);
246 rb_store_relaxed(&rb->write_idx, 0);
247#ifdef CONFIG_RING_BUFFER
267 __ASSERT(size <= RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
269 rb->size = (ring_buf_size_t)size;
293 ring_buf_idx_t write_idx = rb_load_relaxed(&rb->write_idx);
294 ring_buf_idx_t read_idx = rb_load_acquire(&rb->read_idx);
295 ring_buf_idx_t
off, avail;
299 write_idx = rb_idx_advance((
size_t)write_idx + offset, rb->size);
302 if (write_idx >= rb->size) {
303 off = write_idx - rb->size;
304 avail = (read_idx >= rb->size ? rb->size : read_idx) -
off;
307 avail = (read_idx >= rb->size ? read_idx - rb->size : rb->size) -
off;
309 *data = &rb->buffer[
off];
324 size_t write_idx = rb_load_relaxed(&rb->write_idx);
327 rb_store_release(&rb->write_idx, rb_idx_advance(write_idx + size, rb->size));
349 ring_buf_idx_t read_idx = rb_load_relaxed(&rb->read_idx);
350 ring_buf_idx_t write_idx = rb_load_acquire(&rb->write_idx);
351 ring_buf_idx_t
off, avail;
355 read_idx = rb_idx_advance((
size_t)read_idx + offset, rb->size);
358 if (read_idx >= rb->size) {
359 off = read_idx - rb->size;
360 avail = (write_idx >= rb->size ? write_idx : 2U * rb->size) - read_idx;
363 avail = (write_idx >= rb->size ? rb->size : write_idx) - read_idx;
365 *data = &rb->buffer[
off];
380 size_t read_idx = rb_load_relaxed(&rb->read_idx);
383 rb_store_release(&rb->read_idx, rb_idx_advance(read_idx + size, rb->size));
404 chunk =
MIN(avail, size - total);
408 memcpy(dst, &data[total], chunk);
410 }
while (total < size);
434 chunk =
MIN(avail, size - total);
439 memcpy(&data[total], src, chunk);
442 }
while (total < size);
469 chunk =
MIN(avail, size - total);
473 memcpy(&data[total], src, chunk);
475 }
while (total < size);
480#ifdef CONFIG_RING_BUFFER
497#define RING_BUF_ITEM_DECLARE(name, size32) \
498 BUILD_ASSERT((size32) <= RING_BUFFER_MAX_SIZE / 4, RING_BUFFER_SIZE_ASSERT_MSG); \
499 static uint32_t __noinit _ring_buffer_data_##name[(size32)]; \
500 struct ring_buf name = RING_BUF_INIT((uint8_t *)_ring_buffer_data_##name, 4 * (size32))
511#define RING_BUF_ITEM_DECLARE_SIZE(name, size32) \
512 RING_BUF_ITEM_DECLARE(name, (size32))
524#define RING_BUF_ITEM_DECLARE_POW2(name, pow) \
525 RING_BUF_ITEM_DECLARE(name, BIT(pow))
535#define RING_BUF_ITEM_SIZEOF(expr) DIV_ROUND_UP(sizeof(expr), sizeof(uint32_t))
553 __ASSERT(size <= RING_BUFFER_MAX_SIZE / 4, RING_BUFFER_SIZE_ASSERT_MSG);
599 rb->put_claimed += claimed;
628 if (rb->put_claimed < size) {
666 rb->get_claimed += claimed;
695 if (rb->get_claimed < size) {
716static inline void z_rb_write_no_commit(
struct ring_buf *rb,
const uint8_t *data,
726 chunk =
MIN(avail, size -
off);
760 struct ring_element header;
768 header.length = size32;
769 header.value = value;
770 z_rb_write_no_commit(buf, (
const uint8_t *)&header,
sizeof(header), 0);
771 z_rb_write_no_commit(buf, (
const uint8_t *)data, size,
sizeof(header));
804 struct ring_element header;
811 if (data !=
NULL && (header.length > *size32)) {
812 *size32 = header.length;
816 *size32 = header.length;
818 *value = header.value;
835static inline void ring_buf_internal_reset(
struct ring_buf *rb, ring_buf_idx_t value)
837 ring_buf_size_t lim = 2U * rb->size;
839 value = (lim != 0U) ? (ring_buf_idx_t)(value % lim) : 0U;
840 rb_store_relaxed(&rb->read_idx, value);
841 rb_store_relaxed(&rb->write_idx, value);
851#define Z_RING_BUF_CLAIM_REMOVED(name) \
853 BUILD_ASSERT(0, #name "() is deprecated and not available " \
854 "when CONFIG_RING_BUFFER=n. Enable " \
855 "CONFIG_RING_BUFFER to keep it during the " \
856 "deprecation period, or migrate as described in the " \
857 "Zephyr 4.5 migration guide."); \
861#define Z_RING_BUF_DECLARE_REMOVED(name) \
862 BUILD_ASSERT(0, #name " is deprecated and not available when " \
863 "CONFIG_RING_BUFFER=n. Enable CONFIG_RING_BUFFER " \
864 "to keep it during the deprecation period, or migrate as " \
865 "described in the Zephyr 4.5 migration guide.")
867#define ring_buf_put_claim(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_put_claim)
868#define ring_buf_put_finish(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_put_finish)
869#define ring_buf_get_claim(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_get_claim)
870#define ring_buf_get_finish(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_get_finish)
871#define ring_buf_item_init(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_item_init)
872#define ring_buf_item_put(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_item_put)
873#define ring_buf_item_get(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_item_get)
874#define ring_buf_item_space_get(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_item_space_get)
875#define ring_buf_internal_reset(...) Z_RING_BUF_CLAIM_REMOVED(ring_buf_internal_reset)
877#define RING_BUF_ITEM_DECLARE(...) Z_RING_BUF_DECLARE_REMOVED(RING_BUF_ITEM_DECLARE)
878#define RING_BUF_ITEM_DECLARE_SIZE(...) Z_RING_BUF_DECLARE_REMOVED(RING_BUF_ITEM_DECLARE_SIZE)
879#define RING_BUF_ITEM_DECLARE_POW2(...) Z_RING_BUF_DECLARE_REMOVED(RING_BUF_ITEM_DECLARE_POW2)
irp nz macro MOVR cc s mov cc s endm endr irp aw macro LDR aa off
Definition asm-macro-32-bit-gnu.h:20
static uint32_t ring_buf_capacity_get(const struct ring_buf *rb)
Return ring buffer capacity.
Definition ring_buffer.h:175
static bool ring_buf_is_empty(const struct ring_buf *rb)
Determine if a ring buffer is empty.
Definition ring_buffer.h:218
static uint32_t ring_buf_size_get(const struct ring_buf *rb)
Determine size of available data in a ring buffer.
Definition ring_buffer.h:187
static uint32_t ring_buf_space_get(const struct ring_buf *rb)
Determine free space in a ring buffer.
Definition ring_buffer.h:206
static void ring_buf_commit(struct ring_buf *rb, size_t size)
Indicate number of bytes written to a ring buffer.
Definition ring_buffer.h:322
static uint32_t ring_buf_get(struct ring_buf *rb, uint8_t *data, uint32_t size)
Read data from a ring buffer.
Definition ring_buffer.h:425
static uint32_t ring_buf_put_ptr(struct ring_buf *rb, uint8_t **data, size_t offset)
Get address of region for writing data to a ring buffer.
Definition ring_buffer.h:291
static void ring_buf_consume(struct ring_buf *rb, size_t size)
Indicate number of bytes consumed from a ring buffer.
Definition ring_buffer.h:378
static bool ring_buf_is_full(const struct ring_buf *rb)
Determine if a ring buffer is full.
Definition ring_buffer.h:233
static void ring_buf_reset(struct ring_buf *rb)
Reset ring buffer state.
Definition ring_buffer.h:243
static void ring_buf_init(struct ring_buf *rb, uint32_t size, uint8_t *data)
Initialize a ring buffer for byte data.
Definition ring_buffer.h:265
static uint32_t ring_buf_get_ptr(struct ring_buf *rb, uint8_t **data, size_t offset)
Get address of valid data within a ring buffer.
Definition ring_buffer.h:347
static uint32_t ring_buf_peek(const struct ring_buf *rb, uint8_t *data, uint32_t size)
Peek at data from a ring buffer without consuming it.
Definition ring_buffer.h:460
static uint32_t ring_buf_put(struct ring_buf *rb, const uint8_t *data, uint32_t size)
Write (copy) data to a ring buffer.
Definition ring_buffer.h:395
#define IS_ENABLED(config_macro)
Check for macro definition in compiler-visible expressions.
Definition util_macro.h:154
#define MIN(a, b)
Obtain the minimum of two values.
Definition util.h:406
#define EINVAL
Invalid argument.
Definition errno.h:61
#define EMSGSIZE
Message size.
Definition errno.h:107
#define EAGAIN
No more contexts.
Definition errno.h:50
#define NULL
Definition iar_missing_defs.h:20
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
void * memcpy(void *ZRESTRICT d, const void *ZRESTRICT s, size_t n)
A structure to represent a ring buffer.
Definition ring_buffer.h:62