nRF5 SDK v13.0.0
Experimental: Flash Storage

Flash Storage (or fstorage for short) is a module for storing and erasing data in persistent flash storage. The module serves as a wrapper around the SoftDevice flash API. It accepts requests to store data or erase data pages and queues these requests up for asynchronous handling. The application is notified of the operation results through callbacks to registered event handlers.

Fstorage automatically splits up large writes and erases into smaller operations, thus enabling the SoftDevice to handle these requests between radio operations. Failed flash operations that are not accepted or not scheduled by the SoftDevice are retried.

Experimental: Flash Data Storage internally uses fstorage. The module can be used directly as well.

Registering usage

The fstorage module can be used by different applications or different parts of an application at the same time (but not by multiple threads). Each user of flash storage must register with the module to request a number of pages of storage. A page in fstorage is a physical flash page, whose size depends on the chip. The module then grants access to these registered pages only; it is not possible to access the flash using addresses outside of the registered pages. All registered users use their own callback handler and receive updates for the pages that they are registered to use.

Usage registration is done at compile time through the use of Experimental: Section variables. You must provide a function pointer to use for event callbacks, the number of pages to reserve, and a priority that specifies how space is assigned in flash. These parameters are specified at compile time and cannot be changed during run time.

Note
If you update your application and want to retain existing application data, you must not change the priority or number of flash pages that are reserved for each module. To add pages for a new module, register them with a lower priority than the ones that are already in use.

To register usage in fstorage, call the FS_REGISTER_CFG macro that is defined in fstorage.h. Place code similar to the following example code in the application to create a section variable fs_config that contains the specified configuration for fstorage:

#include "fstorage.h"
{
.callback = fs_evt_handler, // Function for event callbacks.
.num_pages = NUM_PAGES, // Number of physical flash pages required.
.priority = 0xFE // Priority for flash usage.
};

Event handler

The following example code shows the signature of the event handler:

static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result)
{
if (result != FS_SUCCESS)
{
// An error occurred.
}
}

Priority for flash usage

For each module registration, you must specify the priority with which fstorage assigns flash space to the module. Possible values are 0 to 255, where 255 is reserved for usage by the Peer Manager. All configured priorities must be unique.

Flash storage assigns flash space with the highest memory address (right below the bootloader, if present) to the module with the highest priority. So if, for example, module 1 has low priority and needs one page and module 2 has high priority and needs two pages, fstorage assigns two pages starting with the highest memory address to module 2 and one page, starting after the two pages, to module 1.

Initializing

The following code example shows how to initialize fstorage:

fs_ret_t ret = fs_init();
if (ret != FS_SUCCESS)
{
// An error occurred.
}

Storing and erasing data

Flash storage queues requests for flash operations and interfaces with the SoftDevice to get timeslots for handling these operations in a timely manner. Large store requests are split up to better negotiate with the SoftDevice to get the wanted timeslots. The maximum number of words in one store request can be specified in the FS_MAX_WRITE_SIZE_WORDS define in fstorage_config.h. Requests to erase multiple pages are split up into individual page erases.

If the SoftDevice does not accept a request, fstorage repeats the queued operation until the SoftDevice accepts the request. If the SoftDevice accepts the request but fails to schedule the flash operation so that it times out (for example, because of high BLE activity), fstorage repeats the request for a configurable number of times. The maximum number of retries can be specified in the FS_OP_MAX_RETRIES define in fstorage_config.h. The registered user is notified about success or failure by an event callback.

The following code example shows how to store data, assuming that fs_config is a section variable that holds the fstorage configuration:

static uint32_t data = 0xAAAAAAAA;
fs_ret_t ret = fs_store(&fs_config, fs_config.p_start_addr, &data, 1);
if (ret != FS_SUCCESS)
{
// An error occurred.
}

The following code example shows how to erase pages:

#define PAGE_SIZE_WORDS 1024
// Retrieve the address of a page.
static uint32_t const * address_of_page(uint16_t page_num)
{
return fs_config.p_start_addr + (page_num * PAGE_SIZE_WORDS);
}
// Erase one page (page 0).
ret = fs_erase(&fs_config, address_of_page(0), 1);
if (ret != FS_SUCCESS)
{
// An error occurred.
}
// Erase two pages, starting from page 3.
ret = fs_erase(&fs_config, address_of_page(3), 2);
if (ret != FS_SUCCESS)
{
// An error occurred.
}

Success or failure of each operation is indicated through event callbacks. Therefore, checking the return value confirms only that the function was called successfully, but not whether the operation is actually carried out.


Documentation feedback | Developer Zone | Subscribe | Updated