Byte FIFO for buffering streamed data.
Most embedded systems need to buffer bytes between an interrupt service routine that fills the FIFO and a main loop that empties it, and vice-versa. The high-performance macros can be used to minimize the time spent with interrupts disabled to safely read and write from the byte FIFO.
Dependencies | Notes | Configuration | API Summary | Function Reference
↑ Dependencies
↑ Notes
- Always check
SSF_BFIFO_IS_FULL()beforeSSF_BFIFO_PUT_BYTE()andSSF_BFIFO_IS_EMPTY()beforeSSF_BFIFO_GET_BYTE(); the macros do not perform overflow or underflow checks. - The buffer passed to
SSFBFifoInit()must be exactlyfifoSize + 1bytes.
↑ Configuration
All options are set in ssfoptions.h.
↑ API Summary
| Symbol | Kind | Description |
|---|---|---|
ssfbf_uint_t |
Typedef | FIFO index type; uint8_t when SSF_BFIFO_CONFIG_MAX_BFIFO_SIZE <= 255, uint16_t up to 65535, uint32_t otherwise |
SSFBFifo_t |
Struct | FIFO instance; pass by pointer to all API functions. Do not access fields directly |
SSF_BFIFO_255 |
Constant | Value 255; pass as fifoSize to SSFBFifoInit() for a 255-byte FIFO |
SSF_BFIFO_65535 |
Constant | Value 65535; pass as fifoSize to SSFBFifoInit() for a 65535-byte FIFO (requires SSF_BFIFO_CONFIG_MAX_BFIFO_SIZE >= 65535) |
↑ Function Reference
void SSFBFifoInit(SSFBFifo_t *fifo,
uint32_t fifoSize,
uint8_t *buffer,
uint32_t bufferSize);Initializes a byte FIFO over a caller-supplied buffer. The buffer must be exactly fifoSize + 1
bytes to allow the full fifoSize bytes of capacity (one byte is used internally to distinguish
full from empty).
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
out | SSFBFifo_t * |
Pointer to the FIFO structure to initialize. Must not be NULL. |
fifoSize |
in | uint32_t |
Desired FIFO capacity in bytes. Must not exceed SSF_BFIFO_CONFIG_MAX_BFIFO_SIZE. Use SSF_BFIFO_255 (255) or SSF_BFIFO_65535 (65535) as appropriate. |
buffer |
in | uint8_t * |
Caller-supplied backing buffer. Must not be NULL. Must be at least fifoSize + 1 bytes. |
bufferSize |
in | uint32_t |
Allocated size of buffer. Must equal fifoSize + 1. |
Returns: Nothing.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
/* bf is ready for use with 255 bytes of capacity */void SSFBFifoDeInit(SSFBFifo_t *fifo);De-initializes a byte FIFO, clearing its internal magic marker.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in-out | SSFBFifo_t * |
Pointer to the FIFO to de-initialize. Must not be NULL. |
Returns: Nothing.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoDeInit(&bf);
/* bf is no longer valid */void SSFBFifoPutByte(SSFBFifo_t *fifo,
uint8_t inByte);Puts one byte into the FIFO. Asserts if the FIFO is full. Call SSFBFifoIsFull() or check
SSF_BFIFO_IS_FULL() before calling.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in-out | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. Must not be full. |
inByte |
in | uint8_t |
Byte to insert into the FIFO. |
Returns: Nothing.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
if (SSFBFifoIsFull(&bf) == false)
{
SSFBFifoPutByte(&bf, 0xA5u);
/* FIFO now contains one byte */
}bool SSFBFifoPeekByte(const SSFBFifo_t *fifo,
uint8_t *outByte);Reads the next byte from the FIFO without consuming it. The byte remains in the FIFO and will be returned again on the next peek or get.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | const SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
outByte |
out | uint8_t * |
Receives the next byte. Must not be NULL. |
Returns: true if a byte was available and written to outByte; false if the FIFO is empty.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
uint8_t b;
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoPutByte(&bf, 0xA5u);
if (SSFBFifoPeekByte(&bf, &b))
{
/* b == 0xA5, byte is still in FIFO */
}bool SSFBFifoGetByte(SSFBFifo_t *fifo,
uint8_t *outByte);Removes and returns the next byte from the FIFO.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in-out | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
outByte |
out | uint8_t * |
Receives the consumed byte. Must not be NULL. |
Returns: true if a byte was available and written to outByte; false if the FIFO is empty.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
uint8_t b;
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoPutByte(&bf, 0xA5u);
if (SSFBFifoGetByte(&bf, &b))
{
/* b == 0xA5, byte has been removed from FIFO */
}
/* SSFBFifoIsEmpty(&bf) == true */bool SSFBFifoIsEmpty(const SSFBFifo_t *fifo);Returns true if the FIFO contains no bytes. Performs full argument validation; use SSF_BFIFO_IS_EMPTY() in interrupt-sensitive code paths where overhead must be minimized.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | const SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
Returns: true if the FIFO is empty; false otherwise.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoIsEmpty(&bf); /* returns true */
SSFBFifoPutByte(&bf, 0x01u);
SSFBFifoIsEmpty(&bf); /* returns false */bool SSFBFifoIsFull(const SSFBFifo_t *fifo);Returns true if the FIFO has no space for additional bytes. Performs full argument validation; use SSF_BFIFO_IS_FULL() in interrupt-sensitive code paths where overhead must be minimized.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | const SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
Returns: true if the FIFO is full; false otherwise.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[4 + 1ul];
uint8_t i;
SSFBFifoInit(&bf, 4, bfBuffer, sizeof(bfBuffer));
SSFBFifoIsFull(&bf); /* returns false */
for (i = 0; i < 4; i++) { SSFBFifoPutByte(&bf, i); }
SSFBFifoIsFull(&bf); /* returns true */ssfbf_uint_t SSFBFifoSize(const SSFBFifo_t *fifo);Returns the total capacity of the FIFO in bytes. ssfbf_uint_t is uint8_t, uint16_t, or uint32_t depending on SSF_BFIFO_CONFIG_MAX_BFIFO_SIZE.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | const SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
Returns: Total FIFO capacity in bytes (the fifoSize value passed to SSFBFifoInit()).
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoSize(&bf); /* returns 255 */ssfbf_uint_t SSFBFifoLen(const SSFBFifo_t *fifo);Returns the number of bytes currently stored in the FIFO. ssfbf_uint_t is uint8_t, uint16_t, or uint32_t depending on SSF_BFIFO_CONFIG_MAX_BFIFO_SIZE.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | const SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
Returns: Number of bytes currently stored in the FIFO.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoPutByte(&bf, 0x01u);
SSFBFifoPutByte(&bf, 0x02u);
SSFBFifoLen(&bf); /* returns 2 */ssfbf_uint_t SSFBFifoUnused(const SSFBFifo_t *fifo);Returns the number of free bytes remaining in the FIFO. ssfbf_uint_t is uint8_t, uint16_t, or uint32_t depending on SSF_BFIFO_CONFIG_MAX_BFIFO_SIZE.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | const SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
Returns: Number of free bytes remaining in the FIFO (Size - Len).
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoPutByte(&bf, 0x01u);
SSFBFifoPutByte(&bf, 0x02u);
SSFBFifoUnused(&bf); /* returns 253 *//* Requires SSF_BFIFO_MULTI_BYTE_ENABLE == 1 */
void SSFBFifoPutBytes(SSFBFifo_t *fifo,
const uint8_t *inBytes,
uint32_t inBytesLen);Puts multiple bytes into the FIFO. Asserts if the FIFO does not have enough free space. Requires SSF_BFIFO_MULTI_BYTE_ENABLE.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in-out | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
inBytes |
in | const uint8_t * |
Buffer of bytes to put into the FIFO. Must not be NULL. |
inBytesLen |
in | uint32_t |
Number of bytes to put. FIFO must have at least this many free bytes. |
Returns: Nothing.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
const uint8_t data[] = {0x01u, 0x02u, 0x03u};
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
if (SSFBFifoUnused(&bf) >= sizeof(data))
{
SSFBFifoPutBytes(&bf, data, sizeof(data));
/* FIFO now contains 3 bytes */
}/* Requires SSF_BFIFO_MULTI_BYTE_ENABLE == 1 */
bool SSFBFifoPeekBytes(const SSFBFifo_t *fifo,
uint8_t *outBytes,
uint32_t outBytesSize,
uint32_t *outBytesLen);Copies up to outBytesSize bytes from the FIFO without consuming them. Requires SSF_BFIFO_MULTI_BYTE_ENABLE.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | const SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
outBytes |
out | uint8_t * |
Buffer receiving bytes. Must not be NULL. |
outBytesSize |
in | uint32_t |
Allocated size of outBytes. |
outBytesLen |
out (opt) | uint32_t * |
If not NULL, receives the number of bytes written to outBytes. |
Returns: true if at least one byte was transferred; false if the FIFO was empty.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
uint8_t out[8];
uint32_t outLen;
const uint8_t data[] = {0x01u, 0x02u, 0x03u};
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoPutBytes(&bf, data, sizeof(data));
if (SSFBFifoPeekBytes(&bf, out, sizeof(out), &outLen))
{
/* outLen == 3, out[0..2] == {0x01, 0x02, 0x03}, bytes still in FIFO */
}/* Requires SSF_BFIFO_MULTI_BYTE_ENABLE == 1 */
bool SSFBFifoGetBytes(SSFBFifo_t *fifo,
uint8_t *outBytes,
uint32_t outBytesSize,
uint32_t *outBytesLen);Removes and copies up to outBytesSize bytes from the FIFO. Requires SSF_BFIFO_MULTI_BYTE_ENABLE.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in-out | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
outBytes |
out | uint8_t * |
Buffer receiving bytes. Must not be NULL. |
outBytesSize |
in | uint32_t |
Allocated size of outBytes. |
outBytesLen |
out (opt) | uint32_t * |
If not NULL, receives the number of bytes written to outBytes. |
Returns: true if at least one byte was transferred; false if the FIFO was empty.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
uint8_t out[8];
uint32_t outLen;
const uint8_t data[] = {0x01u, 0x02u, 0x03u};
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSFBFifoPutBytes(&bf, data, sizeof(data));
if (SSFBFifoGetBytes(&bf, out, sizeof(out), &outLen))
{
/* outLen == 3, out[0..2] == {0x01, 0x02, 0x03}, bytes removed from FIFO */
}
/* SSFBFifoIsEmpty(&bf) == true */Direct field-access macros for use in interrupt service routines where function call overhead is
unacceptable. Always check SSF_BFIFO_IS_FULL() before SSF_BFIFO_PUT_BYTE() and
SSF_BFIFO_IS_EMPTY() before SSF_BFIFO_GET_BYTE(); the macros do not perform overflow or underflow
checks and are not thread safe by themselves.
#define SSF_BFIFO_IS_EMPTY(fifo)Returns true if the FIFO contains no bytes. Directly compares the head and tail indices without argument validation.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
Returns: Non-zero (true) if the FIFO is empty; zero (false) otherwise.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
if (SSF_BFIFO_IS_EMPTY(&bf) == false)
{
/* FIFO has data to process */
}#define SSF_BFIFO_IS_FULL(fifo)Returns true if the FIFO has no space for additional bytes. Directly inspects the head and tail indices without argument validation.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. |
Returns: Non-zero (true) if the FIFO is full; zero (false) otherwise.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
if (SSF_BFIFO_IS_FULL(&bf) == false)
{
/* FIFO has space for at least one more byte */
}#define SSF_BFIFO_PUT_BYTE(fifo,
inByte)Writes one byte into the FIFO and advances the head index. Asserts via SSF_ENSURE() that the FIFO
did not overflow after the write. Always check SSF_BFIFO_IS_FULL() before calling.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in-out | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. Must not be full. |
inByte |
in | uint8_t |
Byte to write into the FIFO. |
Returns: Nothing.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
uint8_t rxByte = 0x42u;
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
if (SSF_BFIFO_IS_FULL(&bf) == false)
{
SSF_BFIFO_PUT_BYTE(&bf, rxByte);
}#define SSF_BFIFO_GET_BYTE(fifo,
outByte)Reads and removes one byte from the FIFO and advances the tail index. Asserts via SSF_REQUIRE()
that the FIFO is not empty before reading. Always check SSF_BFIFO_IS_EMPTY() before calling.
| Parameter | Direction | Type | Description |
|---|---|---|---|
fifo |
in-out | SSFBFifo_t * |
Pointer to an initialized FIFO. Must not be NULL. Must not be empty. |
outByte |
out | uint8_t |
Variable that receives the byte read from the FIFO. |
Returns: Nothing.
Example:
SSFBFifo_t bf;
uint8_t bfBuffer[SSF_BFIFO_255 + 1ul];
uint8_t rxByte = 0x42u;
uint8_t b;
SSFBFifoInit(&bf, SSF_BFIFO_255, bfBuffer, sizeof(bfBuffer));
SSF_BFIFO_PUT_BYTE(&bf, rxByte);
if (SSF_BFIFO_IS_EMPTY(&bf) == false)
{
SSF_BFIFO_GET_BYTE(&bf, b);
/* b == 0x42 */
}