| nRF5 SDK v12.0.0 |

Choose documentation: | nRF5 SDK | S130 SoftDevice API | S132 SoftDevice API | S212 SoftDevice API | S332 SoftDevice API

All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Usage

The following code examples show the typical usage of Flash Data Storage in an application.

# Initializing the module

Initialization, like all other operations in FDS that involve writing or erasing flash memory, is an asynchronous operation. Completion of the operation is reported to the application through a callback. Therefore, before initializing FDS, you must register a callback handler to handle FDS events.

The following example code shows how to register a simple event handler with FDS and initialize the module:

// Simple event handler to handle errors during initialization.
static void fds_evt_handler(fds_evt_t const * const p_fds_evt)
{
switch (p_fds_evt->id)
{
case FDS_EVT_INIT:
if (p_fds_evt->result != FDS_SUCCESS)
{
// Initialization failed.
}
break;
default:
break;
}
}
ret_code_t ret = fds_register(fds_evt_handler);
if (ret != FDS_SUCCESS)
{
// Registering of the event handler has failed.
}
ret_code_t ret = fds_init();
if (ret != FDS_SUCCESS)
{
// Handle error.
}

The init operation will return an event notification upon success.

In the Peer Manager, fds_init is part of the initialization function pm_init.

# Writing a record

The following example code shows how to write a record:

#define FILE_ID 0x1111
#define REC_KEY 0x2222
static uint32_t const m_deadbeef = 0xDEADBEEF;
fds_record_t record;
fds_record_desc_t record_desc;
fds_record_chunk_t record_chunk;
// Set up data.
record_chunk.p_data = &m_deadbeef;
record_chunk.length_words = 1;
// Set up record.
record.file_id = FILE_ID;
record.record_key = REC_KEY;
record.record_data.p_chunks = &record_chunk;
record.record_data.num_chunks = 1;
ret_code_t ret = fds_record_write(&record_desc, &record);
if (ret != FDS_SUCCESS)
{
// Handle error.
}

The command is queued up, and the success or failure is indicated through event callbacks. Upon success, the fds_record_write function returns a descriptor for the record, which can be used to further manipulate the record.

# Retrieving data

The following example code shows how to use the find record functionality to retrieve record descriptors for all records that match a specific key and file ID and read their contents:

#define FILE_ID 0x1111
#define REC_KEY 0x2222
fds_flash_record_t flash_record;
fds_record_desc_t record_desc;
fds_find_token_t ftok;
memset(&ftok, 0x00, sizeof(fds_find_token_t));
// Loop until all records with the given key and file ID have been found.
while (fds_record_find(FILE_ID, REC_KEY, &record_desc, &ftok) == FDS_SUCCESS)
{
if (fds_record_open(&record_desc, &flash_record) != FDS_SUCCESS)
{
// Handle error.
}
// Access the record through the flash_record structure.
// Close the record when done.
if (fds_record_close(&record_desc) != FDS_SUCCESS)
{
// Handle error.
}
}

Closing a record with fds_record_close will not invalidate the record descriptor or the fds_flash_record_t structure. The record descriptor can still be used to manipulate the record to, for example, open it again or delete it. However, the data pointed to by the fds_flash_record_t structure might change at any time after the record is closed. So if you need to access the data after closing the record, you must open it again.

# Deleting a record

The following example code shows how to delete a record:

/* Assume a descriptor returned by a call to fds_record_write() or fds_record_find(),
as shown in the previous example. */
fds_record_desc_t descriptor;
ret_code_t ret = fds_record_delete(&descriptor);
if (ret != FDS_SUCCESS)
{
// Error.
}

The operation is queued up, and the success or failure is indicated through event callbacks.

Calling fds_record_delete will not free the flash memory used by the record. To reclaim the flash space used by records that were deleted, run a garbage collection (fds_gc).