1.. _ring_buffers_v2:
2
3Ring Buffers
4############
5
6A :dfn:`ring buffer` is a circular buffer, whose contents are stored in
7first-in-first-out order.
8
9For circumstances where an application needs to implement asynchronous
10"streaming" copying of data, Zephyr provides a ``struct ring_buf``
11abstraction to manage copies of such data in and out of a shared
12buffer of memory.
13
14Two content data modes are supported:
15
16* **Byte mode**: raw bytes can be enqueued and dequeued.
17
18* **Data item mode**: Multiple 32-bit word data items with metadata
19  can be enqueued and dequeued from the ring buffer in
20  chunks of up to 1020 bytes.  Each data item also has two
21  associated metadata values:  a type identifier and a 16-bit
22  integer value, both of which are application-specific.
23
24While the underlying data structure is the same, it is not
25legal to mix these two modes on a single ring buffer instance.  A ring
26buffer initialized with a byte count must be used only with the
27"bytes" API, one initialized with a word count must use the "items"
28calls.
29
30
31.. contents::
32    :local:
33    :depth: 2
34
35Concepts
36********
37
38Any number of ring buffers can be defined (limited only by available RAM). Each
39ring buffer is referenced by its memory address.
40
41A ring buffer has the following key properties:
42
43* A **data buffer** of bytes or 32-bit words. The data buffer contains the raw
44  bytes or 32-bit words that have been added to the ring buffer but not yet
45  removed.
46
47* A **data buffer size**, measured in bytes or 32-bit words. This governs
48  the maximum amount of data (including possible metadata values) the ring
49  buffer can hold.
50
51A ring buffer must be initialized before it can be used. This sets its
52data buffer to empty.
53
54A ``struct ring_buf`` may be placed anywhere in user-accessible
55memory, and must be initialized with :c:func:`ring_buf_init` or
56:c:func:`ring_buf_item_init` before use. This must be provided a region
57of user-controlled memory for use as the buffer itself.  Note carefully that the units of the size of the
58buffer passed change (either bytes or words) depending on how the ring
59buffer will be used later.  Macros for combining these steps in a
60single static declaration exist for convenience.
61:c:macro:`RING_BUF_DECLARE` will declare and statically initialize a ring
62buffer with a specified byte count, where
63:c:macro:`RING_BUF_ITEM_DECLARE` will declare and statically
64initialize a buffer with a given count of 32 bit words.
65:c:macro:`RING_BUF_ITEM_SIZEOF` will compute the size in 32-bit words
66corresponding to a type or an expression.  Note: rounds up if the size is
67not a multiple of 32 bits.
68
69"Bytes" data may be copied into the ring buffer using
70:c:func:`ring_buf_put`, passing a data pointer and byte count.  These
71bytes will be copied into the buffer in order, as many as will fit in
72the allocated buffer.  The total number of bytes copied (which may be
73fewer than provided) will be returned.  Likewise :c:func:`ring_buf_get`
74will copy bytes out of the ring buffer in the order that they were
75written, into a user-provided buffer, returning the number of bytes
76that were transferred.
77
78To avoid multiply-copied-data situations, a "claim" API exists for
79byte mode.  :c:func:`ring_buf_put_claim` takes a byte size value from the
80user and returns a pointer to memory internal to the ring buffer that
81can be used to receive those bytes, along with a size of the
82contiguous internal region (which may be smaller than requested).  The
83user can then copy data into that region at a later time without
84assembling all the bytes in a single region first.  When complete,
85:c:func:`ring_buf_put_finish` can be used to signal the buffer that the
86transfer is complete, passing the number of bytes actually
87transferred.  At this point a new transfer can be initiated.
88Similarly, :c:func:`ring_buf_get_claim` returns a pointer to internal ring
89buffer data from which the user can read without making a verbatim
90copy, and :c:func:`ring_buf_get_finish` signals the buffer with how many
91bytes have been consumed and allows for a new transfer to begin.
92
93"Items" mode works similarly to bytes mode, except that all transfers
94are in units of 32 bit words and all memory is assumed to be aligned
95on 32 bit boundaries.  The write and read operations are
96:c:func:`ring_buf_item_put` and :c:func:`ring_buf_item_get`, and work
97otherwise identically to the bytes mode APIs.  There no "claim" API
98provided for items mode.  One important difference is that unlike
99:c:func:`ring_buf_put`, :c:func:`ring_buf_item_put` will not do a partial
100transfer; it will return an error in the case where the provided data
101does not fit in its entirety.
102
103The user can manage the capacity of a ring buffer without modifying it
104using either :c:func:`ring_buf_space_get` or :c:func:`ring_buf_item_space_get`
105which returns the number of free bytes or free 32-bit item words respectively,
106or by testing the :c:func:`ring_buf_is_empty` predicate.
107
108Finally, a :c:func:`ring_buf_reset` call exists to immediately empty a
109ring buffer, discarding the tracking of any bytes or items already
110written to the buffer.  It does not modify the memory contents of the
111buffer itself, however.
112
113
114Byte mode
115=========
116
117A **byte mode** ring buffer instance is declared using
118:c:macro:`RING_BUF_DECLARE()` and accessed using:
119:c:func:`ring_buf_put_claim`, :c:func:`ring_buf_put_finish`,
120:c:func:`ring_buf_get_claim`, :c:func:`ring_buf_get_finish`,
121:c:func:`ring_buf_put` and :c:func:`ring_buf_get`.
122
123Data can be copied into the ring buffer (see
124:c:func:`ring_buf_put`) or ring buffer memory can be used
125directly by the user. In the latter case, the operation is split into three stages:
126
1271. allocating the buffer (:c:func:`ring_buf_put_claim`) when
128   user requests the destination location where data can be written.
129#. writing the data by the user (e.g. buffer written by DMA).
130#. indicating the amount of data written to the provided buffer
131   (:c:func:`ring_buf_put_finish`). The amount
132   can be less than or equal to the allocated amount.
133
134Data can be retrieved from a ring buffer through copying
135(see :c:func:`ring_buf_get`) or accessed directly by address. In the latter
136case, the operation is split into three stages:
137
1381. retrieving source location with valid data written to a ring buffer
139   (see :c:func:`ring_buf_get_claim`).
140#. processing data
141#. freeing processed data (see :c:func:`ring_buf_get_finish`).
142   The amount freed can be less than or equal or to the retrieved amount.
143
144Data item mode
145==============
146
147A **data item mode** ring buffer instance is declared using
148:c:macro:`RING_BUF_ITEM_DECLARE()` and accessed using
149:c:func:`ring_buf_item_put` and :c:func:`ring_buf_item_get`.
150
151A ring buffer **data item** is an array of 32-bit words from 0 to 1020 bytes
152in length. When a data item is **enqueued** (:c:func:`ring_buf_item_put`)
153its contents are copied to the data buffer, along with its associated metadata
154values (which occupy one additional 32-bit word). If the ring buffer has
155insufficient space to hold the new data item the enqueue operation fails.
156
157A data item is **dequeued** (:c:func:`ring_buf_item_get`) from a ring
158buffer by removing the oldest enqueued item. The contents of the dequeued data
159item, as well as its two metadata values, are copied to areas supplied by the
160retriever. If the ring buffer is empty, or if the data array supplied by the
161retriever is not large enough to hold the data item's data, the dequeue
162operation fails.
163
164Concurrency
165===========
166
167The ring buffer APIs do not provide any concurrency control.
168Depending on usage (particularly with respect to number of concurrent
169readers/writers) applications may need to protect the ring buffer with
170mutexes and/or use semaphores to notify consumers that there is data to
171read.
172
173For the trivial case of one producer and one consumer, concurrency
174control shouldn't be needed.
175
176Internal Operation
177==================
178
179Data streamed through a ring buffer is always written to the next byte
180within the buffer, wrapping around to the first element after reaching
181the end, thus the "ring" structure.  Internally, the ``struct
182ring_buf`` contains its own buffer pointer and its size, and also a
183set of "head" and "tail" indices representing where the next read and write
184operations may occur.
185
186This boundary is invisible to the user using the normal put/get APIs,
187but becomes a barrier to the "claim" API, because obviously no
188contiguous region can be returned that crosses the end of the buffer.
189This can be surprising to application code, and produce performance
190artifacts when transfers need to happen close to the end of the
191buffer, as the number of calls to claim/finish needs to double for such
192transfers.
193
194
195Implementation
196**************
197
198Defining a Ring Buffer
199======================
200
201A ring buffer is defined using a variable of type :c:struct:`ring_buf`.
202It must then be initialized by calling :c:func:`ring_buf_init` or
203:c:func:`ring_buf_item_init`.
204
205The following code defines and initializes an empty **data item mode** ring
206buffer (which is part of a larger data structure). The ring buffer's data buffer
207is capable of holding 64 words of data and metadata information.
208
209.. code-block:: c
210
211    #define MY_RING_BUF_WORDS 64
212
213    struct my_struct {
214        struct ring_buf rb;
215        uint32_t buffer[MY_RING_BUF_WORDS];
216        ...
217    };
218    struct my_struct ms;
219
220    void init_my_struct {
221        ring_buf_item_init(&ms.rb, MY_RING_BUF_WORDS, ms.buffer);
222        ...
223    }
224
225Alternatively, a ring buffer can be defined and initialized at compile time
226using one of two macros at file scope. Each macro defines both the ring
227buffer itself and its data buffer.
228
229The following code defines a **data item mode** ring buffer:
230
231.. code-block:: c
232
233    #define MY_RING_BUF_WORDS 93
234    RING_BUF_ITEM_DECLARE(my_ring_buf, MY_RING_BUF_WORDS);
235
236The following code defines a ring buffer intended to be used for raw bytes:
237
238.. code-block:: c
239
240    #define MY_RING_BUF_BYTES 93
241    RING_BUF_DECLARE(my_ring_buf, MY_RING_BUF_BYTES);
242
243Enqueuing Data
244==============
245
246Bytes are copied to a **byte mode** ring buffer by calling
247:c:func:`ring_buf_put`.
248
249.. code-block:: c
250
251    uint8_t my_data[MY_RING_BUF_BYTES];
252    uint32_t ret;
253
254    ret = ring_buf_put(&ring_buf, my_data, MY_RING_BUF_BYTES);
255    if (ret != MY_RING_BUF_BYTES) {
256        /* not enough room, partial copy. */
257	...
258    }
259
260Data can be added to a **byte mode** ring buffer by directly accessing the
261ring buffer's memory.  For example:
262
263.. code-block:: c
264
265    uint32_t size;
266    uint32_t rx_size;
267    uint8_t *data;
268    int err;
269
270    /* Allocate buffer within a ring buffer memory. */
271    size = ring_buf_put_claim(&ring_buf, &data, MY_RING_BUF_BYTES);
272
273    /* Work directly on a ring buffer memory. */
274    rx_size = uart_rx(data, size);
275
276    /* Indicate amount of valid data. rx_size can be equal or less than size. */
277    err = ring_buf_put_finish(&ring_buf, rx_size);
278    if (err != 0) {
279        /* This shouldn't happen unless rx_size > size */
280	...
281    }
282
283A data item is added to a ring buffer by calling
284:c:func:`ring_buf_item_put`.
285
286.. code-block:: c
287
288    uint32_t data[MY_DATA_WORDS];
289    int ret;
290
291    ret = ring_buf_item_put(&ring_buf, TYPE_FOO, 0, data, MY_DATA_WORDS);
292    if (ret == -EMSGSIZE) {
293        /* not enough room for the data item */
294	...
295    }
296
297If the data item requires only the type or application-specific integer value
298(i.e. it has no data array), a size of 0 and data pointer of :c:macro:`NULL`
299can be specified.
300
301.. code-block:: c
302
303    int ret;
304
305    ret = ring_buf_item_put(&ring_buf, TYPE_BAR, 17, NULL, 0);
306    if (ret == -EMSGSIZE) {
307        /* not enough room for the data item */
308	...
309    }
310
311Retrieving Data
312===============
313
314Data bytes are copied out from a **byte mode** ring buffer by calling
315:c:func:`ring_buf_get`. For example:
316
317.. code-block:: c
318
319    uint8_t my_data[MY_DATA_BYTES];
320    size_t  ret;
321
322    ret = ring_buf_get(&ring_buf, my_data, sizeof(my_data));
323    if (ret != sizeof(my_data)) {
324        /* Fewer bytes copied. */
325    } else {
326        /* Requested amount of bytes retrieved. */
327        ...
328    }
329
330Data can be retrieved from a **byte mode** ring buffer by direct
331operations on the ring buffer's memory.  For example:
332
333.. code-block:: c
334
335    uint32_t size;
336    uint32_t proc_size;
337    uint8_t *data;
338    int err;
339
340    /* Get buffer within a ring buffer memory. */
341    size = ring_buf_get_claim(&ring_buf, &data, MY_RING_BUF_BYTES);
342
343    /* Work directly on a ring buffer memory. */
344    proc_size = process(data, size);
345
346    /* Indicate amount of data that can be freed. proc_size can be equal or less
347     * than size.
348     */
349    err = ring_buf_get_finish(&ring_buf, proc_size);
350    if (err != 0) {
351        /* proc_size exceeds amount of valid data in a ring buffer. */
352	...
353    }
354
355A data item is removed from a ring buffer by calling
356:c:func:`ring_buf_item_get`.
357
358.. code-block:: c
359
360    uint32_t my_data[MY_DATA_WORDS];
361    uint16_t my_type;
362    uint8_t  my_value;
363    uint8_t  my_size;
364    int ret;
365
366    my_size = MY_DATA_WORDS;
367    ret = ring_buf_item_get(&ring_buf, &my_type, &my_value, my_data, &my_size);
368    if (ret == -EMSGSIZE) {
369        printk("Buffer is too small, need %d uint32_t\n", my_size);
370    } else if (ret == -EAGAIN) {
371        printk("Ring buffer is empty\n");
372    } else {
373        printk("Got item of type %u value &u of size %u dwords\n",
374               my_type, my_value, my_size);
375        ...
376    }
377
378Configuration Options
379*********************
380
381Related configuration options:
382
383* :kconfig:option:`CONFIG_RING_BUFFER`: Enable ring buffer.
384
385API Reference
386*************
387
388The following ring buffer APIs are provided by :zephyr_file:`include/zephyr/sys/ring_buffer.h`:
389
390.. doxygengroup:: ring_buffer_apis
391