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'. |
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. |
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. |
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. |
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. |
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. |
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. |
The total number of bytes contained within the buffer.