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.
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
- Copyright
- Copyright 2014, Peter A. Bigot. Licensed under BSD-3-Clause
#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:
uint8_t allocation[(size_) +
sizeof(
sFIFO)]; \
} allocation_ = { { 0, 0,
sizeof(allocation_) - offsetof(
sFIFO, cell) } }
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
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.
Return a true value iff fp
has no buffered values.
Return a true value iff fp
has no room for additional buffered values.
Return the number of cells actively used by the FIFO.
This ranges from zero to fp->size - 1
.
Copy multiple elements from the FIFO into a buffer.
- Parameters
-
fp | pointer the FIFO pointer |
bps | a pointer to the first location into which FIFO contents should be stored |
bpe | a 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.
Return the oldest value within the FIFO, or a negative error code.
- Parameters
-
fp | pointer to the FIFO structure |
force_if_empty | If 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.
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
-
fp | the FIFO pointer |
v | the 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.
Reset the FIFO back to an empty state.