This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Fstorage vs. SoftDevice activity: application halts when writing to flash if waiting to write or data not correctly written if not waiting

Dear Madam/Sir,

I'm working with SDK14.2, softdevice5.0.0-2alpha, s140, and nRF52840 through the DevKit.

I'm recurring to the fstorage API to read/write/erase flash while using the SoftDevice and respective BLE activity.

When erasing and subsequently writing to the flash (see flash_write_setup() below), in order to get the data correctly written I wait for the commands to get accomplished before continuing running the application, as follows:

static void fstorage_erase(uint32_t addr, uint32_t pages_cnt)
{
    ret_code_t rc = nrf_fstorage_erase(
		&fstorage,      /* The fstorage instance to use. */
		addr,           /* The initial address of the flash pages to erase. */
		pages_cnt,      /* The number of pages to erase. */
		NULL);          /* Optional parameter, backend-dependent. */

    if (rc != NRF_SUCCESS)
    {
        NRF_LOG_INFO("nrf_fstorage_erase() returned: %s",
                        nrf_strerror_get(rc));
    }
    APP_ERROR_CHECK(rc);
}

static void fstorage_write(uint32_t addr, void const * p_data)
{
    /* The following code snippet make sure that the length of the data we are writing to flash
     * is a multiple of the program unit of the flash peripheral (4 bytes).
     *
     * In case of non-string piece of data, use the sizeof operator instead of strlen.
     */
    //uint32_t len = round_up_u32(strlen(p_data)); //THIS CRASHES WHEN DEBUG MODE, WHY?
    uint32_t len = sizeof(p_data);

    ret_code_t rc = nrf_fstorage_write(
		&fstorage,      /* The fstorage instance to use. */
		addr,           /* Address in flash where to write the data. */
		p_data,         /* Data to be written. */
		len,            /* Length of the data (in bytes). */
                NULL);          /* User-defined parameter passed to the event handler (may be NULL). */
    
    if (rc != NRF_SUCCESS)
    {
        NRF_LOG_INFO("nrf_fstorage_write() returned: %s",
                        nrf_strerror_get(rc));
    }
    APP_ERROR_CHECK(rc);
}
void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
{
    /* While fstorage is busy, sleep and wait for an event. */
    while (nrf_fstorage_is_busy(p_fstorage))
    {
        //power_manage()
        ret_code_t err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
    }
}

void flash_write_setup(DEVICE dev)
{
static uint32_t pages_to_erase = 4;
fstorage_erase(m_start_addr_write, pages_to_erase); //m_start_addr_write =0x69000 (my app is not using bootloader)
wait_for_flash_ready(&fstorage);
fstorage_write(m_start_addr_write, &dev); //DEVICE is a struct with three uint8_t fields
wait_for_flash_ready(&fstorage);
}


Yet, if the app is advertising (1.285s interval) or in a connection (275ms interval with slave_latency 3) the app halts and never finishes erasing/writing the data and the app stops working.
If not calling wait_for_flash_ready() after erasing/writing the flash, the app runs smoothly, the data is suposely written after around 2secs and when reading it afterwards the data is wrongly written.

What am I doing wrong and how can I successfully erase/write data in the flash while operating with the SoftDevice and BLE activity?

Thank you,
Best regards,
João