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

fstorage wait_for_flash_ready

Hi!

I know, that there are some similar issues in this forum, and I checked them,
but I didn't see the clue.

I try to use fstorage to write something to flash. I have a running softdevice,
so i use the fstorage_sd backend. I looked at examples/peripheral/flash_storage
and copied some code:

nrf_fstorage_api_t * p_fs_api;

static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);

NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
  .evt_handler = fstorage_evt_handler,
  .start_addr = 0x26000,
  .end_addr   = 0x27fff,
};

static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
{
  if (p_evt->result != NRF_SUCCESS)
  {
    return;
  }

  switch (p_evt->id){
  case NRF_FSTORAGE_EVT_WRITE_RESULT:
    is_written=true;
    break;

  case NRF_FSTORAGE_EVT_ERASE_RESULT:
    is_erased=true;
    break;

  default:
    break;
  }
}

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))
    {
      (void) sd_app_evt_wait();
    }
}

In my init function, I copied the call from example:

p_fs_api = &nrf_fstorage_sd;
uint32_t retcode=nrf_fstorage_init(&fstorage, p_fs_api, NULL);

return of nrf_fstorage_init is NRF_SUCCESS.

when it comes to write, i call (similar to example)

is_written=false;
uint32_t retcode = nrf_fstorage_write(&fstorage, write_addr, data, 16, NULL);
wait_for_flash_ready(&fstorage);


where write_addr is 0x26000 and data is an uint8_t[16].
retcode is NRF_SUCCESS.

But then the problem starts: wait_for_flash_ready() blocks infinitly (until watchdog
bites after 10 s) and the fstorage_evt_handler is not called.
Looking by debugger into flash, the data is written.
If I do not wait_for_flash_ready(&fstorage), the fstorage_evt_handler is called.
If I replace the wait_for_flash_ready by nrf_delay_ms(100), the fstorage_evt_handler
is called after delay is done.
So I guess it has something to do with priorities. But which priorities and where
can I configure them?
I use SD112 and SDK15.3, running on PCA10040

Parents
  • Hello,

    You are most likely correct. It is a priority issue. From where do you call nrf_fstorage_write()? Is it inside an interrupt?

    Now, before you start changing all the interrupt priorities in your project, can you try the same function from your main() function? Does that work?

    int main()
    {
        ... //initialize everything
        ...
        
        is written = false;
        uint32_t retcode = nrf_fstorage_write(&fstorage, write_addr, data, 16, NULL);
        wait_for_flash_ready(&fstorage);
        for (;;)
        {
            //main loop;
            ...
        }
    }

    BR,

    Edvin

  • Thank you for your suggestion. I call the nrf_fstorage_write() from a single shot application timer. When I call it from the main(), it works like a charm.

    So I guess, I have to refactor my code so that I call nrf_fstorage-functions not inside timer-handlers.

    Thanks a lot,

    Dirk.

Reply Children
  • Hello Dirk,

    Exactly. So you are calling the fstorage functions from another interrupt, that probably has the same or higher priority. I don't whether you are using the softdevice or not, but it is not that easy to modify the priority on the fstorage. You can try to set the priority of the app_timer to 7 and see if that helps. Change:

    #define APP_TIMER_CONFIG_IRQ_PRIORITY 6
    to
    #define APP_TIMER_CONFIG_IRQ_PRIORITY 7

    If that doesn't work, one way to handle this is to actually write from your main() function, and use the timer to set a volatile flag which is used in main()

    volatile bool flash_write_flag = false;
    
    app_timer_handler()
    {
        flash_write_flag = true;
    }
    
    
    main()
    {
        ret_code_t err_code;
        //Init everything.
        ...
        
        for (;;)
        {
            if (flash_write_flag)
            {
                err_code = flash_write_function;
                if (err_code = NRF_SUCCESS)
                {
                    flash_write_flag = false;
                }
            }
            if (!NRF_LOG_PROCESS())
            {
                power_manage();
            }
        }
    }

    Best regards,

    Edvin

  • Changing the APP_TIMER_CONFIG_PRIORITY from 6 to 7 works. But I fear the side effects on other places in code, because I use many app_timers.

    So I decided to go the other way, also because it is nearly the same construction I have already to handle similar "low priority long running tasks".

    Thank you very much.

Related