Circular Buffer

Definitions

enum cb_error_t

Errors returned by this library.

Values:

enumerator cb_error_ok

Success, no error.

enumerator cb_error_invalid_args

At least one of the arguments provided is invalid.

enumerator cb_error_full

The circular buffer is full or the specified number of elements do not fit in it.

enumerator cb_error_empty

The circular buffer is empty of the specified number of elements do not exist in it.

enumerator cb_error_evt

The handling of an event in the user provided event handler resulted in error.

enumerator cb_error_count

Number of errors.

enum cb_evt_id_t

Event identifier.

Values:

enumerator cb_evt_id_none

No event, used to subscribe to no events.

enumerator cb_evt_id_read

Request to read underlying linear buffer of the circular buffer.

enumerator cb_evt_id_write

Request to write underlying linear buffer of the circular buffer.

enumerator cb_evt_id_lock

Request to lock circular buffer, this event can’t return cb_error_evt.

enumerator cb_evt_id_unlock

Request to unlock circular buffer, this event can’t return cb_error_evt.

typedef cb_evt_data_unused_t cb_evt_data_lock_t

Event data for cb_evt_id_lock event.

typedef cb_evt_data_unused_t cb_evt_data_unlock_t

Event data for cb_evt_id_unlock event.

typedef cb_error_t (*cb_evt_handler_t)(cb_evt_t *const evt)

Event handler for the circular buffer.

Param evt:

[in] The event.

Retval cb_error_ok:

Success.

Retval cb_error_evt:

An error ocurred in the event handler processing an event.

typedef struct cb_s cb_t

Circular buffer context.

The underlying linear buffer must have an additional element more than the intended size to determine if full or empty, in other words, an additional element is used instead of a full or empty flag.

The buffer is determined to be full when the write or head index is one slot behind the read or tail index. The buffer is determined to be empty when the write or head index is at the same slot as the read or tail index.

User should not modify nor access the members of this structure directly, only through the API in this library.

struct cb_evt_data_unused_t

Unused event data, used for events that do not have any data.

Public Members

size_t unused

The event does not have any data.

struct cb_evt_data_read_t

Event data for cb_evt_id_read event.

Public Members

const void *read_ptr

The read pointer where to read the data from.

size_t bytes

The number of bytes to read from read_ptr and write to buffer.

void *buffer

The buffer where to write data to.

struct cb_evt_data_write_t

Event data for cb_evt_id_write event.

Public Members

const void *buffer

Buffer The buffer where to read the data from.

size_t bytes

The number of bytes to read from buffer and write to write_ptr.

void *write_ptr

The write pointer where to write the data to.

union cb_evt_data_t

Event data.

Public Members

cb_evt_data_read_t read

Event data for cb_evt_id_read event.

cb_evt_data_write_t write

Event data for cb_evt_id_write event.

cb_evt_data_lock_t lock

Event data for cb_evt_id_lock event.

cb_evt_data_unlock_t unlock

Event data for cb_evt_id_unlock event.

struct cb_evt_t

Event.

Public Members

const struct cb_s *cb

The circular buffer that trigerred the event.

void *user_data

The user data passed during initialization of the circular buffer.

cb_evt_data_t data

The event identifier.

struct cb_s

Circular buffer context.

The underlying linear buffer must have an additional element more than the intended size to determine if full or empty, in other words, an additional element is used instead of a full or empty flag.

The buffer is determined to be full when the write or head index is one slot behind the read or tail index. The buffer is determined to be empty when the write or head index is at the same slot as the read or tail index.

User should not modify nor access the members of this structure directly, only through the API in this library.

Public Members

void *buffer

The underlying linear buffer on which the circular buffer operates.

size_t buffer_length

The size of buffer in number of elements of size elem_size.

size_t elem_size

The size of each element in buffer.

atomic_size_t read_idx

The atomic read or tail index, goes from 0 to buffer_length - 1.

atomic_size_t write_idx

The atomic write or head index, goes from 0 to buffer_length - 1.

cb_evt_handler_t evt_handler

Event handler, can be NULL if not suscribed to events.

cb_evt_id_t evt_sub

Suscribed events, OR combination of cb_evt_id_t or cb_evt_id_none.

void *evt_user_data

Event handler user data, will be passed to evt_handler when trigerred.

Public API

cb_error_t cb_init(cb_t *const cb, void *const buffer, const size_t buffer_length, const size_t elem_size, const cb_evt_handler_t evt_handler, const cb_evt_id_t evt_sub, void *const evt_user_data)

Initializes a circular buffer.

Parameters:
  • cb[in] The circular buffer context to initialize.

  • buffer[in] The underlying linear buffer for the circular buffer, with one extra element than intended size.

  • buffer_length[in] The size of buffer in number of elements of size elem_size.

  • elem_size[in] The size of each element in buffer.

  • evt_handler[in] Event handler, can be NULL if not suscribed to events.

  • evt_sub[in] Suscribed events, OR combination of cb_evt_id_t or cb_evt_id_none.

  • evt_user_data[in] Event handler user data, will be passed to evt_handler when trigerred.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.

cb_error_t cb_write(cb_t *const cb, const void *const buffer, const size_t count)

Writes the specified number of elements to the circular buffer.

If all the elements do not fit, nothing is written to the circular buffer.

Parameters:
  • cb[in] The initialized circular buffer context.

  • buffer[in] The buffer with the elements to write to cb.

  • count[in] The number of elements in buffer.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.

  • cb_error_full – The circular buffer is full or can’t fit count elements.

  • cb_error_evt – An error ocurred in the event handler.

cb_error_t cb_read(cb_t *const cb, void *const buffer, const size_t count)

Reads the specified number of elements from the circular buffer.

If the circular buffer does not have the specified number of elements, nothing is read from it.

Parameters:
  • cb[in] The initialized circular buffer context.

  • buffer[in] The buffer where the elements read from cb will be written to.

  • count[in] The number of elements to read from cb.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.

  • cb_error_empty – The circular buffer is empty or does not have count elements.

  • cb_error_evt – An error ocurred in the event handler.

cb_error_t cb_get_unfilled(cb_t *const cb, size_t *const count)

Gets the number of elements that can be written to the buffer before it becomes full.

Parameters:
  • cb[in] The initialized circular buffer context.

  • count[out] The number of unfilled slots in cb.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.

cb_error_t cb_get_filled(cb_t *const cb, size_t *const count)

Gets the number of elements that can be read from the buffer before it becomes empty.

Parameters:
  • cb[in] The initialized circular buffer context.

  • count[out] The number of filled slots in cb.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.

cb_error_t cb_is_empty(cb_t *const cb, bool *const is_empty)

Determines if a buffer is empty and no more data can be written to it.

Parameters:
  • cb[in] The initialized circular buffer context.

  • is_empty[out] On success, true if empty and false if full.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.

cb_error_t cb_is_full(cb_t *const cb, bool *const is_full)

Determines if a buffer is full and no more data can be written to it.

Parameters:
  • cb[in] The initialized circular buffer context.

  • is_full[out] On success, true if full and false if empty.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.

cb_error_t cb_deinit(cb_t *const cb)

Deinitializes a circular buffer.

Parameters:
  • cb[in] The circular buffer context to initialize.

Return values:
  • cb_error_ok – Success.

  • cb_error_invalid_args – At least one of the arguments provided is invalid.