HALFRED  0.4.0
Data Structures | Macros | Typedefs | Functions
IOBuf module

Detailed Description

Introduction.

The IOBuf is a simple implementation of a ring buffer. It is used by several HAL modules and can also be used as a general-purpose buffer by the application.

Inside IOBuf.

The IOBuf consists of a descriptor and memory space (pool) used for storing data. The descriptor holds all the information needed for IOBuf to operate. The IOBuf stores elements of data. A signle element is an array of bytes. The bytesize of an element is fixed for every IOBuf during initialization. Typical examples of elements are bytes (bytesize is simply one), but it could also be pointers or structures.

Using IOBufs.

The IOBuf object must be declared or created at runtime by a call to IOBUF_Create. To declare IOBuf at compile time you must provide the memory pool. The buffer must be then initialized by a call to IOBUF_Init. The following code declares a buffer for 2-byte elements. The IOBuf descriptor is placed on top of the memory pool, so the actual memory pool size is sizeof(IOBufDesc) less.

char iobuf_pool[100];
IOBUF iobuf;
IOBUF_Init(iobuf_pool, sizeof(iobuf_pool), 2);

To create IOBuf at runtime you need a dynamic memory manager (see also notes below). Then all you need to do is call IOBUF_Create. You DO NOT call IOBUF_Init as the buffer is already initialized. The following example allocates a buffer for maximum of 10 elements, each of bytesize 2.

IOBUF iobuf;
iobuf = IOBUF_Create(2, 10);

To destroy it you must call IOBUF_Destroy.

The buffer can be written by a call to IOBUF_Write and read from by a call to IOBUF_Read. The IOBUF_GetCount function returns the number of elements currently stored in the buffer. The IOBUF_GetSpace function returns the number of elements that can still fit into the buffer.

Dynamic memory and IOBufs.

Creating and destroying dynamic IOBufs requires dynamic memory manager. You can select one in your config.h in the HEAP module section.

Data Structures

struct  IOBufDesc
 

Macros

#define IOBUF_DECLARE(name, count, size)
 

Typedefs

typedef size_t iobuf_size_t
 
typedef struct IOBufDescIOBuf
 

Functions

IOBuf IOBUF_Create (iobuf_size_t elem_size, iobuf_size_t max_elem_count)
 
IOBuf IOBUF_Destroy (IOBuf iobuf)
 
iobuf_size_t IOBUF_GetCount (IOBuf iobuf)
 
iobuf_size_t IOBUF_GetSpace (IOBuf iobuf)
 
iobuf_size_t IOBUF_GetSize (IOBuf iobuf)
 
IOBuf IOBUF_Init (void *buf_ptr, iobuf_size_t buf_size, iobuf_size_t elem_size)
 
iobuf_size_t IOBUF_Read (IOBuf iobuf, void *data, iobuf_size_t elem_count)
 
iobuf_size_t IOBUF_Write (IOBuf iobuf, const void *data, iobuf_size_t elem_count)
 
iobuf_size_t IOBUF_ReadNextFragment (IOBuf iobuf, iobuf_size_t fragment_size, void **next_fragment_ptr, iobuf_size_t *next_fragment_size)
 
iobuf_size_t IOBUF_WriteNextFragment (IOBuf iobuf, iobuf_size_t fragment_size, void **next_fragment_ptr, iobuf_size_t *next_fragment_size)
 
iobuf_size_t IOBUF_ReadFast (IOBuf iobuf, void *elem)
 
iobuf_size_t IOBUF_WriteFast (IOBuf iobuf, const void *elem)
 
void IOBUF_Clear (IOBuf iobuf)
 
iobuf_size_t IOBUF_Peek (IOBuf iobuf, void *data, iobuf_size_t elem_count)
 
iobuf_size_t IOBUF_Move (IOBuf dst_iobuf, IOBuf src_iobuf, iobuf_size_t elem_count)
 
iobuf_size_t IOBUF_Remove (IOBuf iobuf, iobuf_size_t elem_count)
 

Macro Definition Documentation

#define IOBUF_DECLARE (   name,
  count,
  size 
)
Value:
static uint8_t name##_mempool[(count)*(size)]; \
static IOBufDesc name = { 0, size, count, &name##_mempool, &name##_mempool, &name##_mempool };
Definition: hal_iobuf.h:88

Macro that declares a static IOBuffer

Function Documentation

IOBuf IOBUF_Create ( iobuf_size_t  elem_size,
iobuf_size_t  max_elem_count 
)

Creates a buffer. Allocates the memory for the buffer and its descriptor.

Returns
handle of the created buffer or NULL, if there were errors.
Parameters
elem_sizesize in bytes of asingle element that can be stored in a buffer
max_elem_countmaximum number of elements that the buffer can store (size of bufer)
IOBuf IOBUF_Destroy ( IOBuf  iobuf)

Destroys a buffer, freeing memory for the buffer pool and the descriptor.

Parameters
iobufhandle of the buffer to destroy
iobuf_size_t IOBUF_GetCount ( IOBuf  iobuf)

Returns the number of elements stored in a buffer.

Parameters
iobufhandle of the buffer
iobuf_size_t IOBUF_GetSpace ( IOBuf  iobuf)

Returns the number of elements that can still be written to a buffer.

Returns
actual number of elements that can be written or 0, if the buffer handle is invalid or buffer is full.
Parameters
iobufhandle of the buffer
iobuf_size_t IOBUF_GetSize ( IOBuf  iobuf)

Returns the total number of elements that the buffer can store (buffer capacity).

Returns
buffer capacity
Parameters
iobufhandle of the buffer
IOBuf IOBUF_Init ( void *  buf_ptr,
iobuf_size_t  buf_size,
iobuf_size_t  elem_size 
)

Initializes a buffer inside the specified memory area, allowing static memory allocation. This area must be big enough to hold the iobuf memory pool and the iobuf descriptor. The actual memory usage for the buffer is elem_size * buf_count + sizeof(IOBufDesc). The buffer descriptor is placed at the beginning of the specified memory area, so after successful initialization, the returned handle will be the same as buf_ptr.

Returns
handle of a newly initialized buffer or NULL if initialization failed
Parameters
buf_ptrpointer to a memory area that will be used by the buffer
buf_sizesize of the memory area
elem_sizesize in bytes of a single element in the buffer
iobuf_size_t IOBUF_Read ( IOBuf  iobuf,
void *  data,
iobuf_size_t  elem_count 
)

Reads a specified number of elements from a buffer. The data is copied from the buffer's internal memory pool to the destination space, pointed by the data parameter.

Returns
number of elements actually read
Parameters
iobufhandle of the buffer
datapointer to the destination space
elem_countnumber of elements to read
iobuf_size_t IOBUF_Write ( IOBuf  iobuf,
const void *  data,
iobuf_size_t  elem_count 
)

Writes a specified number of elements to a buffer. The data is copied from the provided source space to the buffer's internal memory pool.

Returns
number of elements actually written
Parameters
iobufhandle of the buffer
datapointer to the source data
elem_countnumber of elements to write
iobuf_size_t IOBUF_ReadNextFragment ( IOBuf  iobuf,
iobuf_size_t  fragment_size,
void **  next_fragment_ptr,
iobuf_size_t *  next_fragment_size 
)

Reads a portion of data from a buffer by returning a pointer to the next fragment of data. This function differs from IOBUF_Read, because in this case there is no data copying. This function gives out a pointer to sequential memory blocks from the buffer's internal memory pool, and acts like the caller actualy read it (by progressing buffer's internal read mark).

This function tries to read as much as possible at once. This means, that it will try to read max_fragment_size elements. However, this may not be possible for two reasons:

  • the buffer stores less elements (obvious)
  • the requested data wraps around the buffer's internal memory pool (that's because of the ring-nature of the buffer)

In the second case, the requested data is actually split in the memory, and no consistent memory block can be returned. Only the first data block will be returned, the second one will be read during the next function call, even though it stored in the buffer already.

Parameters
iobufhandle of the buffer
fragment_sizespecifies the maximum amount of elements that can be read by this call (the requested data size)
next_fragment_ptrpointer to a variable, where a pointer to the next portion of data to read will be stored
next_fragment_sizepointer to a variable, where the size of the next portion of data to read will be stored
iobuf_size_t IOBUF_WriteNextFragment ( IOBuf  iobuf,
iobuf_size_t  fragment_size,
void **  next_fragment_ptr,
iobuf_size_t *  next_fragment_size 
)

Allows to write data directly to the buffer's internal memory pool avoiding in some cases the unnecessary data copying, while still operating in the ring-buffer fashion. This function gets a pointer and size of the memory block and acts as it was actually written (by progressing buffer's internal write mark). By using this function, the caller actually requests sequential blocks of space in the ring-buffer.

This function tries to get as much space as possible at once. This means, that it will try to get space for fragment_size elements. However, this may not be possible for two reasons:

  • the buffer capacity is exceeded (obvious)
  • the requested data space wraps around the buffer's internal memory pool (that's because of the ring-nature of the buffer)

In the second case, the requested data space is actually split in the memory, and no consistent memory block can be requested. Only the first data block will be returned, the second one will be returned during the next function call, even though it may be ready in the buffer.

Parameters
iobufhandle of the buffer
fragment_sizespecifies the amount of elements that the caller wants to write to the buffer
next_fragment_ptrpointer to a variable, where a pointer to the next available data chunk will be stored
next_fragment_sizepointer to a variable, where the size of the available data chunk will be stored. This can be less or equal to the fragment_size parameter.
iobuf_size_t IOBUF_ReadFast ( IOBuf  iobuf,
void *  elem 
)

Reads a single element from a buffer, without utilizing any critical sections (fast call). This function is only safe to call when global interrupts are disabled, in example inside non-nestable interrupt service routine.

Parameters
iobufhandle of the buffer
elemdestination buffer
Returns
number of element read (0 or 1)
iobuf_size_t IOBUF_WriteFast ( IOBuf  iobuf,
const void *  elem 
)

Writes a single element to a buffer, without utilizing any critical sections (fast call). This function is only safe to call when global interrupts are disabled, in example inside non-nestable interrupt service routine.

Parameters
iobufhandle of the buffer
elemsource data buffer
Returns
number of element written (0 or 1)
void IOBUF_Clear ( IOBuf  iobuf)

Clears the content stored in the buffer, making it return to initial state.

Parameters
iobufhandle of the buffer
iobuf_size_t IOBUF_Peek ( IOBuf  iobuf,
void *  data,
iobuf_size_t  elem_count 
)

Reads a specified number of elements from a buffer, but without altering the state of the buffer. The data read is not removed from the buffer. This means that two sequential calls will return the same data. The data is copied from the buffer's internal memory pool to the destination space, pointed by the data parameter.

Returns
number of elements actually read
Parameters
iobufhandle of the buffer
datapointer to the destination space
elem_countnumber of elements to read
iobuf_size_t IOBUF_Move ( IOBuf  dst_iobuf,
IOBuf  src_iobuf,
iobuf_size_t  elem_count 
)

Moves a specified number of elements from the source buffer into the destination buffer. It may fail to move the desired number of elements due to:

  • destination buffer overrun
  • source buffer underrun In any of the above cases, this function will move as much data as possible.
Returns
number of elements actually moved
Parameters
dst_iobufhandle of the destination buffer
src_iobufhandle of the source buffer
elem_countnumber of elements to move
iobuf_size_t IOBUF_Remove ( IOBuf  iobuf,
iobuf_size_t  elem_count 
)

Removes a specified number of elements from a buffer. The data is removed from the buffer's internal memory pool and discarded.

Returns
number of elements actually removed
Parameters
iobufhandle of the buffer
elem_countnumber of elements to remove