Skip to content

Latest commit

 

History

History
715 lines (490 loc) · 22 KB

File metadata and controls

715 lines (490 loc) · 22 KB

ssfbfifo — Byte FIFO Interface

SSF | Data Structures

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

Configuration

All options are set in ssfoptions.h.

Option Default Description
SSF_BFIFO_CONFIG_MAX_BFIFO_SIZE 255 Maximum FIFO capacity in bytes; determines the integer width of internal index fields
SSF_BFIFO_CONFIG_RUNTIME_BFIFO_SIZE SSF_BFIFO_CONFIG_RUNTIME_BFIFO_SIZE_255 Allowed runtime sizes: ANY, 255, or POW2_MINUS1
SSF_BFIFO_MULTI_BYTE_ENABLE 1 1 to enable multi-byte put/peek/get functions

API Summary

Definitions

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)

Functions

Function / Macro Description
e.g. void SSFBFifoInit(fifo, fifoSize, buffer, bufferSize) Initialize a byte FIFO
e.g. void SSFBFifoDeInit(fifo) De-initialize a byte FIFO
e.g. void SSFBFifoPutByte(fifo, inByte) Put one byte (bounds-checked function)
e.g. bool SSFBFifoPeekByte(fifo, outByte) Peek at the next byte without consuming it
e.g. bool SSFBFifoGetByte(fifo, outByte) Get (consume) one byte
e.g. bool SSFBFifoIsEmpty(fifo) Returns true if FIFO is empty
e.g. bool SSFBFifoIsFull(fifo) Returns true if FIFO is full
e.g. ssfbf_uint_t SSFBFifoSize(fifo) Returns the FIFO capacity in bytes
e.g. ssfbf_uint_t SSFBFifoLen(fifo) Returns the number of bytes currently in the FIFO
e.g. ssfbf_uint_t SSFBFifoUnused(fifo) Returns the number of free bytes remaining
e.g. void SSFBFifoPutBytes(fifo, inBytes, inBytesLen) Put multiple bytes (requires SSF_BFIFO_MULTI_BYTE_ENABLE)
e.g. bool SSFBFifoPeekBytes(fifo, outBytes, outBytesSize, outBytesLen) Peek at multiple bytes (requires SSF_BFIFO_MULTI_BYTE_ENABLE)
e.g. bool SSFBFifoGetBytes(fifo, outBytes, outBytesSize, outBytesLen) Get multiple bytes (requires SSF_BFIFO_MULTI_BYTE_ENABLE)
e.g. SSF_BFIFO_IS_EMPTY(fifo) Macro: true if FIFO is empty (no bounds check)
e.g. SSF_BFIFO_IS_FULL(fifo) Macro: true if FIFO is full (no bounds check)
e.g. SSF_BFIFO_PUT_BYTE(fifo, b) Macro: put one byte (no overflow check, asserts post-put)
e.g. SSF_BFIFO_GET_BYTE(fifo, b) Macro: get one byte (asserts non-empty, no check)

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 */
}