BSPACM  20150113
Board Support Package for ARM Cortex-M Microcontrollers
Data Structures | Macros | Typedefs | Functions
fifo.h File Reference

Header for a first-in-first-out supporting datastructure. More...

#include <bspacm/core.h>
#include <stddef.h>

Go to the source code of this file.

Data Structures

struct  sFIFO
 

Macros

#define FIFO_DEFINE_ALLOCATION(allocation_, size_)
 
#define FIFO_FROM_ALLOCATION(allocation_)   (&(allocation_).fifo)
 
#define FIFO_ADJUST_OFFSET(fp_, v_)   ((v_) % (fp_)->size)
 

Typedefs

typedef struct sFIFO sFIFO
 

Functions

static BSPACM_CORE_INLINE void fifo_reset (sFIFO *fp)
 
static BSPACM_CORE_INLINE uint16_t fifo_length (const sFIFO *fp)
 
static BSPACM_CORE_INLINE int fifo_empty (const sFIFO *fp)
 
static BSPACM_CORE_INLINE int fifo_full (const sFIFO *fp)
 
static BSPACM_CORE_INLINE int fifo_pop_tail (sFIFO *fp, int force_if_empty)
 
static BSPACM_CORE_INLINE int fifo_push_head (sFIFO *fp, uint8_t v)
 
static BSPACM_CORE_INLINE int fifo_pop_into_buffer (sFIFO *fp, uint8_t *bps, uint8_t *bpe)
 

Detailed Description

Header for a first-in-first-out supporting datastructure.

Warning
This header is intended to be included in implementation files only. The types, macros, and functions described are not namespace-clean.
All fifo_* operations are assumed to operate in mutex context: i.e. no other system (thread, interrupt handler, etc) may be interacting with the FIFO. See sFIFO for details.
Homepage
http://github.com/pabigot/bspacm

Macro Definition Documentation

#define FIFO_ADJUST_OFFSET (   fp_,
  v_ 
)    ((v_) % (fp_)->size)

Perform the adjustments necessary to convert a head/tail offset back into the domain of the FIFO cell buffer.

Parameters
fp_a pointer to an sFIFO instance
v_a uint16_t value that may have been incremented past the size of fp_'s cell buffer
Returns
the offset of the cell that is identified by v_ modulo the size of fp_'s cell buffer

(Oddly, making this an inline function increases code size; hence it is a macro.)

#define FIFO_DEFINE_ALLOCATION (   allocation_,
  size_ 
)
Value:
static union { \
sFIFO fifo; \
uint8_t allocation[(size_) + sizeof(sFIFO)]; \
} allocation_ = { { 0, 0, sizeof(allocation_) - offsetof(sFIFO, cell) } }
struct sFIFO sFIFO
Definition: fifo.h:101

Define a sFIFO instance that supports at least size_ value cells.

Warning
The definition has static storage class. A reference to the fifo instance must be shared with the infrastructure that uses it.
See also
FIFO_FROM_ALLOCATION()
Parameters
allocation_the name of the allocation instance
size_the desired number of cells. The actual number of cells may be slightly larger due to alignment padding.
#define FIFO_FROM_ALLOCATION (   allocation_)    (&(allocation_).fifo)

Obtain a pointer to the sFIFO instance stored within allocation_, which must have been defined using FIFO_DEFINE_ALLOCATION().

Parameters
allocation_the name of the allocation instance
Returns
a pointer to the sFIFO instance within the allocation

Typedef Documentation

typedef struct sFIFO sFIFO

Data structure for a first-in-first-out circular buffer of arbitrary size, holding octet (uint8_t) values.

This struct uses the flexible array capability standardized in C99, along with the FIFO_DEFINE_ALLOCATION() and FIFO_FROM_ALLOCATION() macros, to avoid dynamic memory allocation while still allowing variation in size between instances of the data type.

Invariants and policies:

  • head is equal to tail only when the FIFO is empty.
  • head+1 is equal to tail modulo size when the FIFO is full.
  • Values are added at the head, which then moves to the next cell.
  • Values are removed from the tail, which then moves to the next cell.
  • Newly-received values are retained in preference to older values when the buffer overflows.

This data structure is intended to be shared between interrupt handlers and framework code. It probably should not be accessed directly by user code. The following operations are provided to help maintain the invariants above:

Although these inline functions perform common operations, for full efficiency it is sometimes necessary to manipulate the head and tail fields directly. The fields that are expected to be read and written by both interrupt handlers and framework code are marked volatile to ensure they are not cached inappropriately. Nonetheless, all changes to the volatile fields of this structure must be done in a context that inhibits external modifications. As an optimization, framework code executed with interrupts off may use local cached variables holding head or tail while performing operations that involve multiple cells of the buffer, so long as the final values are written back to the structure before interrupts are re-enabled. Be sure to satisfy the data structure invariants when writing such code.

Function Documentation

static BSPACM_CORE_INLINE int fifo_empty ( const sFIFO fp)
static

Return a true value iff fp has no buffered values.

static BSPACM_CORE_INLINE int fifo_full ( const sFIFO fp)
static

Return a true value iff fp has no room for additional buffered values.

static BSPACM_CORE_INLINE uint16_t fifo_length ( const sFIFO fp)
static

Return the number of cells actively used by the FIFO.

This ranges from zero to fp->size - 1.

static BSPACM_CORE_INLINE int fifo_pop_into_buffer ( sFIFO fp,
uint8_t *  bps,
uint8_t *  bpe 
)
static

Copy multiple elements from the FIFO into a buffer.

Parameters
fppointer the FIFO pointer
bpsa pointer to the first location into which FIFO contents should be stored
bpea pointer to the end location, immediately following the last location where a FIFO value may be stored
Returns
the number of elements stored starting at bps. The smaller of bpe-bps and the length of the FIFO will be copied out.
static BSPACM_CORE_INLINE int fifo_pop_tail ( sFIFO fp,
int  force_if_empty 
)
static

Return the oldest value within the FIFO, or a negative error code.

Parameters
fppointer to the FIFO structure
force_if_emptyIf this is a true value, the tail of the FIFO will be adjusted to consume its last value, whether or not there appears to be such a value. This allows a new value to be stored into the array prior to checking whether there is space for it, and causes the oldest unread value to be forgotten. When false, the tail will not be incremented if it appears there no values.
Returns
a non-negative value from the buffer, or a negative value indicating that the FIFO was empty.
static BSPACM_CORE_INLINE int fifo_push_head ( sFIFO fp,
uint8_t  v 
)
static

Push v onto FIFO fp.

The return value indicates the previous state of the FIFO, allowing interrupt configuration to follow the empty/non-empty/full state of the FIFO. In all cases v will be saved; in some cases an earlier value in the FIFO will be lost.

Parameters
fpthe FIFO pointer
vthe value to be added
Returns
A negative value if the fifo was full (this will save the new value, but discard the oldest unread value); zero if the value was saved to a fifo that already had values in it; a positive value if the value was saved to a previously-empty FIFO.
static BSPACM_CORE_INLINE void fifo_reset ( sFIFO fp)
static

Reset the FIFO back to an empty state.