Circular Buffers

The circular buffer component is part of the real-time kernel and provides byte-wide copy-in/copy-out storage of generic data. A buffer supports blocking of threads when reading and writing the buffer. Buffers also support being read and written from either a thread or an interrupt service routine (ISR).

Basic Usage

The code snippet below creates a static circular buffer that is written from an interrupt service routine while a thread is blocked waiting for the data to arrive.

#include "Kernel/kernel_buffer.h"
#include <assert.h>

/* Application-defined message that is transferred through a buffer */
typedef struct MSG {
    UINT32 time;
    UINT32 data;
} MSG;

static BUFFER buffer;                       /* Allocate a buffer */

void APP_Function(void* arg)
{
    static BYTE bufmem[256];                /* Allocate memory to be used by the buffer */
    STATUS status;
    MSG msg;


    status = BUFFER_Create(&buffer,         /* Create the circular buffer */
                           "Buffer1",       /* A name for the buffer (for debugging purposes) */
                           bufmem,          /* A pointer to the memory managed by the buffer */
                           sizeof(bufmem)); /* The size, in bytes, of the memory managed by the buffer */

    assert(status == SUCCESS);

    APP_EnableInterrupt();                  /* Enable the interrupt source that will write to the buffer... */


    for(;;) {

        status = BUFFER_Read(&buffer,       /* Block and wait for a message to be received */
                             &msg,          /* A pointer to receive the data from the buffer */
                             sizeof(MSG),   /* The number of bytes to receive from the buffer */
                             NULL,          /* A pointer to a variable to receive how many bytes were received (NULL for all or nothing) */
                             INFINITE);     /* Block indefinitely until a message arrives */

        if (status == SUCCESS) {

            /* A message has been received */
        }
    }
}

void ISR_Function(void)
{
    STATUS status;
    MSG msg;


    msg.time = KERNEL_Timestamp();          /* Create some random message */
    msg.data = rand();

    status = BUFFER_Write(&buffer,          /* Write the message to the buffer */
                          &msg,             /* A pointer to the data to be copied into the buffer */
                          sizeof(MSG),      /* The number of bytes to be copied into the buffer */
                          NULL,             /* A pointer to receive how many bytes were copied (NULL for all or nothing) */
                          0);               /* Don't block (unable to from ISR anyways) */
						  
    assert(status == SUCCESS);
}

API Reference

STATUS BUFFER_Create(BUFFER* b, const CHAR* name, void* mem, UINT32 capacity)
Creates and initializes a circular buffer.
PARAMETERS
b A pointer to a caller allocated buffer to be initialized.
name A pointer to a NULL terminated string that represents a name for the buffer
mem A pointer to a caller allocated array of memory that will hold the contents of the buffer.
capacity The maximum amount of data in bytes that the buffer can contain. Must not be larger than the memory provided by argument 'mem'.
RETURNS
SUCCESS The buffer was created and initialized.
ERR_NULLREFERENCE The argument 'b' or 'mem' was found to be NULL.
ERR_INVALIDCONTEXT The operation is not supported from the context of an interrupt service routine (ISR).
ERR_INVALIDARGUMENT The specified interval must be larger than zero.
ERR_ALREADYINITIALIZED The specified buffer has already been created and initialized.
STATUS BUFFER_Destroy(BUFFER* b)
Destroys and removes a buffer from the kernel. Any threads that happen to be blocked waiting to write or read from the buffer will be released with the ERR_DESTROYED status code.
PARAMETERS
b A pointer to a buffer to be destroyed.
RETURNS
SUCCESS The buffer was destroyed and removed from the kernel.
ERR_NULLREFERENCE The argument 'b' was found to be NULL.
ERR_INVALIDCONTEXT The operation is not supported from the context of an interrupt service routine (ISR).
ERR_NOTINITIALIZED The specified buffer has not been created or initialized.
STATUS BUFFER_Clear(BUFFER* b)
Clears and removes all contents of a buffer.
PARAMETERS
b A pointer to the buffer to be cleared.
RETURNS
SUCCESS The buffer has been cleared.
ERR_NULLREFERENCE The argument 'b' was found to be NULL.
ERR_NOTINITIALIZED The specified buffer has not been created or initialized.
STATUS BUFFER_Write(BUFFER* b, const void* data, UINT32 nbytes, UINT32* actual, UINT32 timeout)
Writes data to a circular buffer.
PARAMETERS
b A pointer to the buffer to receive the data.
data A pointer to the beginning of the data to be written into the buffer.
nbytes The total number of data bytes to be written into the buffer.
actual A pointer to a caller allocated value used to determine the actual number of bytes that have been written to the buffer. Use 'NULL' to force either all or none of the data to be written.
timeout The maximum amount of time, in kernel ticks, to block and wait for sufficient space to fulfill the request. Use 0 to return immediately without blocking and use INFINITE to wait indefinitely.
RETURNS
SUCCESS The data has been written to the buffer. Use 'actual' to determine the number of bytes actually written.
ERR_NULLREFERENCE The argument 'b' or 'data' was found to be NULL.
ERR_ACCESSDENIED The request is from an interrupt and the buffer was already being written by a thread.
ERR_TIMEOUT The specified amount of time has elapsed before there was sufficient space within the buffer.
STATUS BUFFER_Read(BUFFER* b, void* buf, UINT32 nbytes, UINT32* actual, UINT32 timeout)
Reads and removes data from a circular buffer.
PARAMETERS
b A pointer to the buffer object that contains the data to be removed.
buf A pointer to a caller allocated buffer to receive the data read and removed from the buffer.
nbytes The total number of bytes to be read and removed from the buffer.
actual A pointer to a caller allocated value used to determine the actual number of bytes that have been returned. Use 'NULL' to only return either all or none of the requested amount.
timeout The maximum amount of time, in kernel ticks, to block and wait for the data to be received. Use '0' to return immediately without blocking and use 'INFINITE' wait indefinitely.
RETURNS
SUCCESS The operation completed successfully. Use argument 'actual' to determine the number of bytes returned.
ERR_NULLREFERENCE The argument 'b' or 'buf' was found to be NULL.
ERR_ACCESSDENIED The buffer was being accessed by a thread.
ERR_TIMEOUT The specified amount of time has elapsed before the requested amount of data arrived within the buffer.
UINT32 BUFFER_Capacity(BUFFER* b)
Returns the capacity, in bytes, for a buffer.
PARAMETERS
b A pointer to the target buffer.
RETURNS
The specified buffer's capacity, in bytes.
UINT32 BUFFER_Count(BUFFER* b)
Returns the number of bytes currently contained within a buffer.
PARAMETERS
b A pointer to the target buffer.
RETURNS
The total number of bytes contained within the buffer.