PebbleOS
Loading...
Searching...
No Matches
Data Structures | Functions
Circular buffer

Single-reader, single-writer byte ring buffer. More...

Data Structures

struct  CircularBuffer
 Circular buffer state. More...
 

Functions

void circular_buffer_init (CircularBuffer *buffer, uint8_t *storage, uint16_t storage_size)
 Initialize a circular buffer, with auto reset enabled.
 
void circular_buffer_init_ex (CircularBuffer *buffer, uint8_t *storage, uint16_t storage_size, bool auto_reset)
 Initialize a circular buffer, choosing whether it auto resets.
 
bool circular_buffer_write (CircularBuffer *buffer, const void *data, uint16_t length)
 Copy data into the circular buffer.
 
uint16_t circular_buffer_write_prepare (CircularBuffer *buffer, uint8_t **data_out)
 Get a contiguous area of the circular buffer to write to directly.
 
void circular_buffer_write_finish (CircularBuffer *buffer, uint16_t written_length)
 Commit data written after circular_buffer_write_prepare().
 
bool circular_buffer_read (const CircularBuffer *buffer, uint16_t length, const uint8_t **data_out, uint16_t *length_out)
 Get a pointer to the oldest data, without consuming it.
 
uint16_t circular_buffer_copy (const CircularBuffer *buffer, void *data_out, uint16_t length)
 Copy the oldest data out of the circular buffer, without consuming it.
 
uint16_t circular_buffer_copy_offset (const CircularBuffer *buffer, uint16_t start_offset, uint8_t *data_out, uint16_t length)
 Copy data out of the circular buffer, handling the wrap, without consuming it.
 
bool circular_buffer_read_or_copy (const CircularBuffer *buffer, uint8_t **data_out, size_t length, void *(*malloc_imp)(size_t), bool *caller_should_free)
 Get the oldest data as one contiguous array, copying it only when it wraps.
 
bool circular_buffer_consume (CircularBuffer *buffer, uint16_t length)
 Remove the oldest data from the circular buffer.
 
uint16_t circular_buffer_get_write_space_remaining (const CircularBuffer *buffer)
 Get the free space.
 
uint16_t circular_buffer_get_read_space_remaining (const CircularBuffer *buffer)
 Get the amount of data.
 

Detailed Description

Single-reader, single-writer byte ring buffer.

Data is written and consumed in a circular fashion over caller-provided storage: a write that reaches the end of the storage wraps around to its start, using space freed by consumed data. Reads do not consume, so the reader can work on the data in place and consume it afterwards. There is no locking.

static uint8_t s_storage[256];
static CircularBuffer s_buf;
circular_buffer_init(&s_buf, s_storage, sizeof(s_storage));
circular_buffer_write(&s_buf, msg, msg_len);
const uint8_t *data;
uint16_t len;
while (avail > 0) {
circular_buffer_read(&s_buf, avail, &data, &len); // len stops at the end of the storage
process(data, len);
avail -= len;
}
Circular buffer state.
Definition circular_buffer.h:41
void circular_buffer_init(CircularBuffer *buffer, uint8_t *storage, uint16_t storage_size)
Initialize a circular buffer, with auto reset enabled.
uint16_t circular_buffer_get_read_space_remaining(const CircularBuffer *buffer)
Get the amount of data.
bool circular_buffer_consume(CircularBuffer *buffer, uint16_t length)
Remove the oldest data from the circular buffer.
bool circular_buffer_read(const CircularBuffer *buffer, uint16_t length, const uint8_t **data_out, uint16_t *length_out)
Get a pointer to the oldest data, without consuming it.
bool circular_buffer_write(CircularBuffer *buffer, const void *data, uint16_t length)
Copy data into the circular buffer.

Data Structure Documentation

◆ CircularBuffer

struct CircularBuffer

Circular buffer state.

Data Fields
bool auto_reset Rewind to the start of the storage when the buffer empties.
uint8_t * buffer Storage.
uint16_t buffer_size Size of buffer in bytes.
uint16_t data_length Bytes of valid data starting at read_index.
uint16_t read_index Offset in buffer to read from next.
bool write_in_progress A circular_buffer_write_prepare() is pending its circular_buffer_write_finish().

Function Documentation

◆ circular_buffer_consume()

bool circular_buffer_consume ( CircularBuffer *  buffer,
uint16_t  length 
)

Remove the oldest data from the circular buffer.

Parameters
bufferCircular buffer.
lengthNumber of bytes to remove.
Returns
false if there are fewer than length bytes in the buffer (nothing is removed).

◆ circular_buffer_copy()

uint16_t circular_buffer_copy ( const CircularBuffer *  buffer,
void *  data_out,
uint16_t  length 
)

Copy the oldest data out of the circular buffer, without consuming it.

Same as circular_buffer_copy_offset() with an offset of 0.

Parameters
bufferCircular buffer.
[out]data_outDestination.
lengthMaximum number of bytes to copy.
Returns
Number of bytes copied.

◆ circular_buffer_copy_offset()

uint16_t circular_buffer_copy_offset ( const CircularBuffer *  buffer,
uint16_t  start_offset,
uint8_t *  data_out,
uint16_t  length 
)

Copy data out of the circular buffer, handling the wrap, without consuming it.

Parameters
bufferCircular buffer.
start_offsetNumber of bytes of the oldest data to skip.
[out]data_outDestination.
lengthMaximum number of bytes to copy.
Returns
Number of bytes copied, 0 if there is no data past start_offset.

◆ circular_buffer_get_read_space_remaining()

uint16_t circular_buffer_get_read_space_remaining ( const CircularBuffer *  buffer)

Get the amount of data.

Parameters
bufferCircular buffer.
Returns
Number of bytes available to read.

◆ circular_buffer_get_write_space_remaining()

uint16_t circular_buffer_get_write_space_remaining ( const CircularBuffer *  buffer)

Get the free space.

Parameters
bufferCircular buffer.
Returns
Number of bytes circular_buffer_write() can take.

◆ circular_buffer_init()

void circular_buffer_init ( CircularBuffer *  buffer,
uint8_t *  storage,
uint16_t  storage_size 
)

Initialize a circular buffer, with auto reset enabled.

Parameters
[out]bufferCircular buffer.
storageStorage, must outlive buffer.
storage_sizeSize of storage in bytes.

◆ circular_buffer_init_ex()

void circular_buffer_init_ex ( CircularBuffer *  buffer,
uint8_t *  storage,
uint16_t  storage_size,
bool  auto_reset 
)

Initialize a circular buffer, choosing whether it auto resets.

With auto reset, the read and write positions go back to the start of the storage whenever circular_buffer_consume() empties the buffer, to reduce wrapping. Without it the buffer always wraps and old data stays in the storage, which is handy for post-mortem analysis of debug logs.

Parameters
[out]bufferCircular buffer.
storageStorage, must outlive buffer.
storage_sizeSize of storage in bytes.
auto_resetWhether to auto reset.

◆ circular_buffer_read()

bool circular_buffer_read ( const CircularBuffer *  buffer,
uint16_t  length,
const uint8_t **  data_out,
uint16_t *  length_out 
)

Get a pointer to the oldest data, without consuming it.

When the requested data wraps around the end of the storage, only the part up to the end is returned and length_out is smaller than length; read again after consuming it to get the rest. data_out stays valid until the data is consumed.

Parameters
bufferCircular buffer.
lengthNumber of bytes to read.
[out]data_outStart of the data.
[out]length_outNumber of contiguous bytes at data_out.
Returns
false if there are fewer than length bytes in the buffer.

◆ circular_buffer_read_or_copy()

bool circular_buffer_read_or_copy ( const CircularBuffer *  buffer,
uint8_t **  data_out,
size_t  length,
void *(*)(size_t)  malloc_imp,
bool *  caller_should_free 
)

Get the oldest data as one contiguous array, copying it only when it wraps.

Parameters
bufferCircular buffer.
[out]data_outStart of the data, NULL if the copy could not be allocated.
lengthNumber of bytes to get.
malloc_impAllocator for the copy.
[out]caller_should_freeSet when data_out is a copy the caller must free.
Returns
false if there are fewer than length bytes in the buffer or the allocation failed.

◆ circular_buffer_write()

bool circular_buffer_write ( CircularBuffer *  buffer,
const void *  data,
uint16_t  length 
)

Copy data into the circular buffer.

Parameters
bufferCircular buffer.
dataData to write.
lengthNumber of bytes to write.
Returns
true on success, false if there is not enough space (nothing is written).

◆ circular_buffer_write_finish()

void circular_buffer_write_finish ( CircularBuffer *  buffer,
uint16_t  written_length 
)

Commit data written after circular_buffer_write_prepare().

Parameters
bufferCircular buffer.
written_lengthNumber of bytes written at the area returned by circular_buffer_write_prepare().

◆ circular_buffer_write_prepare()

uint16_t circular_buffer_write_prepare ( CircularBuffer *  buffer,
uint8_t **  data_out 
)

Get a contiguous area of the circular buffer to write to directly.

Call circular_buffer_write_finish() once done writing, so the buffer accounts for the data. Only one such write may be in progress.

Parameters
bufferCircular buffer.
[out]data_outStart of the writable area, or NULL if there is no space or a write is already in progress.
Returns
Number of bytes that can be written at data_out, 0 if none.