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