Atomic FIFO implementation

nRF5 SDK v12.2.0

nRF52 Series only: FIFO implementation that allows for making atomic transactions without locking interrupts. More...

Modules

Atomic operations API
nRF52 Series only: This module implements C11 stdatomic.h simplified API. At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions). Atomic types are limited to nrf_atomic_u32_t and nrf_atomic_flag_t .
FIFO instance macros

Data Structures

struct nrf_atfifo_postag_pos_s
Read and write position structure. More...
union nrf_atfifo_postag_u
End data index tag. More...
struct app_atfifo_s
The FIFO instance. More...
struct app_atfifo_wcontext_s
FIFO write operation context. More...
struct app_atfifo_rcontext_s
FIFO read operation context. More...

Typedefs

typedef struct
nrf_atfifo_postag_pos_s
nrf_atfifo_postag_pos_t
Read and write position structure. More...
typedef union nrf_atfifo_postag_u nrf_atfifo_postag_t
End data index tag. More...
typedef struct app_atfifo_s app_atfifo_t
The FIFO instance. More...
typedef struct
app_atfifo_wcontext_s
app_atfifo_wcontext_t
FIFO write operation context. More...
typedef struct
app_atfifo_rcontext_s
app_atfifo_rcontext_t
FIFO read operation context. More...

Functions

ret_code_t app_atfifo_init ( app_atfifo_t *const p_fifo, void *p_buf, uint16_t buf_size, uint16_t item_size)
Initializing the FIFO. More...
ret_code_t app_atfifo_clear ( app_atfifo_t *const p_fifo)
Clear the FIFO. More...
ret_code_t app_atfifo_put ( app_atfifo_t *const p_fifo, void const *const p_var, size_t size, bool *const p_visible)
Put data into FIFO. More...
void * app_atfifo_wopen_internal ( app_atfifo_t *const p_fifo, app_atfifo_wcontext_t *p_context)
Open FIFO for writing, internal function. More...
static void * app_atfifo_wopen ( app_atfifo_t *const p_fifo, app_atfifo_wcontext_t *p_context, size_t size)
Open FIFO for writing. More...
bool app_atfifo_wcommit ( app_atfifo_t *const p_fifo, app_atfifo_wcontext_t *p_context)
Close the writing operation. More...
ret_code_t app_atfifo_get ( app_atfifo_t *const p_fifo, void *const p_var, size_t size, bool *p_released)
Get single value from the FIFO. More...
void const * app_atfifo_ropen_internal ( app_atfifo_t *const p_fifo, app_atfifo_rcontext_t *p_context)
Open FIFO for reading, internal function. More...
static void const * app_atfifo_ropen ( app_atfifo_t *const p_fifo, app_atfifo_rcontext_t *p_context, size_t size)
Open FIFO for reading. More...
bool app_atfifo_rflush ( app_atfifo_t *const p_fifo, app_atfifo_rcontext_t *p_context)
Close reading operation. More...

Detailed Description

nRF52 Series only: FIFO implementation that allows for making atomic transactions without locking interrupts.

There are two types of functions to prepare FIFO writing:

  • Single function for simple access:
    if (NRF_SUCCESS != nrf_atfifo_put(&my_fifo, &data, NULL))
    {
    // Error handling
    }
  • Function pair to limit data coping:
    struct point3d
    {
    int x, y, z;
    }point3d_t;
    nrf_atfifo_context_t context;
    point3d_t * point;
    if (NULL != (point = nrf_atfifo_wopen(&my_fifo, &context)))
    {
    point->x = a;
    point->y = b;
    point->z = c;
    if (nrf_atfifo_wcommit(&my_fifo, &context))
    {
    // Send an information to the rest of the system
    // that there is new data in the FIFO available to read.
    }
    }
    else
    {
    // Error handling
    }
    Note
    This Atomic FIFO implementation requires that the operation that was opened last would be finished (committed/flushed) first. This is typical for operations performed from the interrupt runtime when the other operation is performed from main thread.
    This implementation does not support typical multithreading operating system access where operations can be started and finished in totally unrelated order.

Typedef Documentation

FIFO read operation context.

Context structure used to mark opened read operation. All the data required to properly flush the accessed data after accessing.

The FIFO instance.

The instance of atomic FIFO. Used with all FIFO functions.

FIFO write operation context.

Context structure used to mark opened commit. All the data required to properly access the data and then commit it after writing.

Read and write position structure.

A structure that holds read and write position used by fifo head and tail.

End data index tag.

A tag used to mark end of data. To properly realize atomic data committing the whole variable has to be accessed atomically.

Function Documentation

ret_code_t app_atfifo_clear ( app_atfifo_t *const p_fifo )

Clear the FIFO.

Clearing the FIFO.

If this function is called during some opened and uncommitted write operation, the FIFO would be cleared up to the currently ongoing commit. There is no possibility to cancel ongoing commit.

If this function is called during some opened and unflushed read operation, the read position in head would be set, but copying it into write head position would be left to read closing operation.

This way there would be no more data to read, but the memory would be released in the moment when it is safe.

Parameters
[in,out] p_fifo FIFO object.
Return values
NRF_SUCCESS FIFO totally cleared
NRF_ERROR_BUSY Function called in the middle of writing or reading operation. If we are in the middle of writing operation, FIFO was cleared up to the already started, and uncommitted write. If we are in the middle of write operation, write head was only moved. It would be copied into read tail when reading operation would be flushed.
ret_code_t app_atfifo_get ( app_atfifo_t *const p_fifo ,
void *const p_var ,
size_t size ,
bool * p_released
)

Get single value from the FIFO.

Function gets the value from the top from the FIFO. The value is removed from the FIFO memory.

Parameters
[in,out] p_fifo FIFO object.
[out] p_var Pointer to the variable to store data.
[in] size Size of the data we are going to load.
[out] p_released See the values returned by app_atfifo_rflush .
Return values
NRF_SUCCESS Element was successfully copied from FIFO memory.
NRF_ERROR_NOT_FOUND No data in the FIFO.
ret_code_t app_atfifo_init ( app_atfifo_t *const p_fifo ,
void * p_buf ,
uint16_t buf_size ,
uint16_t item_size
)

Initializing the FIFO.

Preparing FIFO instance to work.

Parameters
[out] p_fifo FIFO object to initialize.
[in,out] p_buf FIFO buffer for storing data.
[in] buf_size Total buffer size (has to be divisible by item_size ).
[in] item_size Size of single item hold inside the FIFO.
Return values
NRF_SUCCESS If initialization was successful.
NRF_ERROR_NULL If a NULL pointer is provided as buffer.
NRF_ERROR_INVALID_LENGTH If size of buffer provided is divisible by item_size .
Note
Buffer size has to be able to fit 1 element more than designed FIFO capacity. This one, empty element is used for overflow checking.
ret_code_t app_atfifo_put ( app_atfifo_t *const p_fifo ,
void const *const p_var ,
size_t size ,
bool *const p_visible
)

Put data into FIFO.

Function to that puts data into the FIFO atomically.

Parameters
[in,out] p_fifo FIFO object.
[in] p_var Variable to copy.
[in] size Size of the variable to copy. Can be smaller or equal to the FIFO item size.
[out] p_visible See value returned by app_atfifo_wcommit . If may be NULL if the caller does not care about current operation status.
Return values
NRF_SUCCESS If an element has been successfully added to the FIFO.
NRF_ERROR_NO_MEM If the FIFO is full.
Note
To avoid data copying one may use app_atfifo_wopen and app_atfifo_wcommit functions pair.
bool app_atfifo_rflush ( app_atfifo_t *const p_fifo ,
app_atfifo_rcontext_t * p_context
)

Close reading operation.

Function used to finish reading operation. If this reading operation did not interrupt another reading operation the head write buffer is moved. If this reading operation was placed in the middle of another reading, the new read pointer is only written.

Parameters
[in,out] p_fifo FIFO object.
[in] p_context Context of the reading operation that we are going to close.
Return values
true This operation is not generated in the middle of another read operation and the write head would be updated to read head (space is released).
false This operation was performed in the middle of another read operation and the write buffer head was not moved (no space is released).
static void const* app_atfifo_ropen ( app_atfifo_t *const p_fifo ,
app_atfifo_rcontext_t * p_context ,
size_t size
)
inline static

Open FIFO for reading.

Function called to start FIFO read operation and access the FIFO buffer directly.

Parameters
[in,out] p_fifo FIFO object.
[out] p_context The operation context, required by app_atfifo_rflush
[in] size Requested size of the buffer. Currently used only for integrity checking when debugging.
Returns
Pointer to data buffer or NULL if there is no data in the FIFO.
void const* app_atfifo_ropen_internal ( app_atfifo_t *const p_fifo ,
app_atfifo_rcontext_t * p_context
)

Open FIFO for reading, internal function.

Function called to start FIFO read operation and access the given FIFO buffer directly.

Parameters
[in,out] p_fifo FIFO object.
[out] p_context The operation context, required by app_atfifo_rflush
Returns
Pointer to data buffer or NULL if there is no data in the FIFO.
Note
Do not use this function directly. Use app_atfifo_ropen instead.
bool app_atfifo_wcommit ( app_atfifo_t *const p_fifo ,
app_atfifo_wcontext_t * p_context
)

Close the writing operation.

Function need to be called to finally commit opened write operation. It sets all the buffers and finally mark the data to be visible to read.

Parameters
[in,out] p_fifo FIFO object.
[in] p_context Operation context, filled by the app_atfifo_wopen function.
Return values
true The data is actually ready and would be visible to read.
false The internal commit was marked, but the writing operation interrupted another writing operation. The data would be available to read when the interrupted operation would be committed.
static void* app_atfifo_wopen ( app_atfifo_t *const p_fifo ,
app_atfifo_wcontext_t * p_context ,
size_t size
)
inline static

Open FIFO for writing.

Function called to start FIFO write operation and access the given FIFO buffer directly.

Parameters
[in,out] p_fifo FIFO object.
[out] p_context The operation context, required by app_atfifo_wcommit .
[in] size Requested size of the buffer. Currently used only for integrity checking when debugging.
Returns
Pointer to the space where variable data may be stored. NULL if there is no space in the buffer.
Note
Always finish writing operation by app_atfifo_wcommit
void* app_atfifo_wopen_internal ( app_atfifo_t *const p_fifo ,
app_atfifo_wcontext_t * p_context
)

Open FIFO for writing, internal function.

Function called to start FIFO write operation and access the given FIFO buffer directly.

Parameters
[in,out] p_fifo FIFO object.
[out] p_context The operation context, required by app_atfifo_wcommit .
Returns
Pointer to the space where variable data may be stored. NULL if there is no space in the buffer.
Note
Do not use this function directly. Use app_atfifo_wopen instead.