flash not completely written with fstorage

I am using a custom board based on nRF52840. Application is working perfectly, and then a new feature was requested. I need to count the number of minutes the application has been running, up to a small number.

I used the example fstorage code to find the end of flash, backed up a page and initialized fstorage to use that page. I use app_timer to set a 60-second timer, and when it fires I use nrf_fstorage_write to write 32 bits of zero to the previously erased flash. 

When running with the debugger the 32-bit word is always written to zeros. But when I "free run" the board from power-up, and then later (minutes later) attach the debugger and have a look, I see that where I have written zeros the words in flash are not entirely zero. 

This is not a crisis, as *some* of the bits are written to zero and I only need know on the next boot whether the words are non-0xffffffff. But I am bothered and a little puzzled. 

The code, simplified, is essentially as below. Note that I just extracted this from my code and have not actually run this extract. If someone wishes to do so I can update the code to make it runnable. 

NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
   .end_addr = 0x100000,
   .start_addr = 0xfd000,
   .evt_handler = fstorage_evt_handler,

static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
    if (p_evt->result != NRF_SUCCESS)
        NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");

    switch (p_evt->id)
            NRF_LOG_INFO("\n--> Event received: wrote %d bytes at address 0x%x.",
                         p_evt->len, p_evt->addr);
        } break;


uint32_t g_minutes_used = 0;
uint32_t g_minutes_left = MAX_RUNTIME_MINUTES;

static void timer_runtime_event_handler(void* p_context)

   ** this handler is called every minute.

   const uint32_t zero_value = 0;

   nrf_fstorage_write(&fstorage, (uint32_t)&my_flash_start[g_minutes_used], &zero_value, sizeof(zero_value), NULL);

   NRF_LOG_INFO("\n    Wrote zero to 0x%x. minutes left = %d.",(uint32_t)&my_flash_start[g_minutes_used],g_minutes_left);



int fstorage_init(void)
    ret_code_t rc;

    NRF_LOG_INFO("\nfstorage example started.");

    nrf_fstorage_api_t * p_fs_api;

    NRF_LOG_INFO("\nSoftDevice is present.");
    NRF_LOG_INFO("\nInitializing nrf_fstorage_sd implementation...");
    /* Initialize an fstorage instance using the nrf_fstorage_sd backend.
     * nrf_fstorage_sd uses the SoftDevice to write to flash. This implementation can safely be
     * used whenever there is a SoftDevice, regardless of its status (enabled/disabled). */
    p_fs_api = &nrf_fstorage_sd;
    NRF_LOG_INFO("\nSoftDevice not present.");
    NRF_LOG_INFO("\nInitializing nrf_fstorage_nvmc implementation...");
    /* Initialize an fstorage instance using the nrf_fstorage_nvmc backend.
     * nrf_fstorage_nvmc uses the NVMC peripheral. This implementation can be used when the
     * SoftDevice is disabled or not present.
     * Using this implementation when the SoftDevice is enabled results in a hardfault. */
    p_fs_api = &nrf_fstorage_nvmc;
    ** initialize flash storage code
    rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL);

    ** count how many minutes we've used so far
    uint32_t ix;

    for (ix = 0; ix < MAX_RUNTIME_MINUTES;ix++)
       if (0xffffffff == my_flash_start[ix])
          g_minutes_used = ix; // index into flash
          g_minutes_left = MAX_RUNTIME_MINUTES - g_minutes_used ; // number of minutes left

    ** check to see if we've used all our minutes
    if (ix >= MAX_RUNTIME_MINUTES)
       g_minutes_used = MAX_RUNTIME_MINUTES;
       g_minutes_left = 0;

    NRF_LOG_INFO("\nStartup: minutes used = %d.",g_minutes_used);
    NRF_LOG_INFO("\nStartup: minutes left = %d.",g_minutes_left);

    ** create the & start the runtime timer
    uint32_t err_code;


    err_code = app_timer_create(&m_runtime_timer_id,

    err_code = app_timer_start(m_runtime_timer_id,TICKS_ONE_MINUTE,NULL);


Parents Reply Children
No Data