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

Module requires 3 power cycles to initialize FDS Manager.

Hardware Description:

MKBN02A00 module based on nRF52832 SOC

Software Description 

nRF SDK 15.2.0 , SoftDevice S112

Observation:

When power_manager_init() is called before fds_manager_init(). It requires 3 power cycles to initialize FDS module. For the first 2 power cycle applications stays in wait_for_fds_ready() loop.

When power_manager_init() is called after fds_manager_init(), FDS module initializes on 1st power cycle without any problem.

Question:

What could be the possible reason for such behavior? Does power_management (sleep mode) affects the "fds module initialization" status events being generated/captured for 

fds_evt_handler. And if so why it works fine on the 3rd power cycle. Or if there is any other problem? 

Application Code:

Below is the sequence of initialization in the main function.

    APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    
    // power_management_init();
    ble_stack_init();
    timers_init();
    buttons_leds_init();
    rtc_start();
    
    fds_manager_init();
    load_device_config();
    power_management_init();

fds_manager_init(void) function

void fds_manager_init(void)
{
    ret_code_t ret;

    ret = fds_register(fds_evt_handler);
    if (ret != FDS_SUCCESS)
    {
        // Registering of the FDS event handler has failed.
    }
    
    ret = fds_init();
    if (ret != FDS_SUCCESS)
    {
        // Handle error.
    }

    wait_for_fds_ready();

    fds_stat_t stat = {0};

    ret = fds_stat(&stat);
    APP_ERROR_CHECK(ret);

    fds_gc();
}

wait_for_fds_ready() function

static void wait_for_fds_ready(void)
{
    while (!m_fds_initialized)
    {
       (void) sd_app_evt_wait();
    }
}

power_management_init() calls nrf_pwr_mgmt_int()

ret_code_t nrf_pwr_mgmt_init(void)
{
    m_shutdown_started = false;
    nrf_mtx_init(&m_sysoff_mtx);
    nrf_section_iter_init(&m_handlers_iter, &pwr_mgmt_data);

    PWR_MGMT_SLEEP_INIT();
    PWR_MGMT_DEBUG_PINS_INIT();
    PWR_MGMT_STANDBY_TIMEOUT_INIT();
    PWR_MGMT_CPU_USAGE_MONITOR_INIT();

    return PWR_MGMT_TIMER_CREATE();
}

Parents
  • Hi,

    I've seen similar behavior like this when Softdevice flash events are not being forwarded back to fstorage -> fds. So I suspect the problem may be related to Softdevice event forwarding from the SoftDevice Handler library.  Please confirm if the nrf_sdh_soc.c file is included in your build.

  • Hi Vidar, Thanks for the quick response. 

    Yes, I verified, I have included nrf_sdh_soc.c file in the build.

  • Hello,

    You found the problem. Softdevice events get added to the scheduler queue from the SD IRQ handler when the 'NRF_SDH_DISPATCH_MODEL_APPSH' model is used, but processing of this queue doesn't start until the program reaches app_sched_execute() in your main loop. The result of this is that the m_fds_initialized flag never gets cleared and wait_for_fds_ready() ends up becoming an endless loop. 

    The solution of manually polling the event will work. Another possible option is to process the scheduler task as shown by the code snippet below, but I don't think there is any real difference between these two methods.

    /**
     * @brief Wait for fds to initialize.
     * 
     */
    static void wait_for_fds_ready(void)
    {
        while (!m_fds_initialized)
        {
           /* Enter System ON idle mode while waiting for SD event */
           (void) sd_app_evt_wait();
           /* Process scheduler queue. Is normally done from main loop only
              and should never be called from interrupt context */
           app_sched_execute();
        }
    }

    Mukesh Kumar said:
    Is it must that NRF_SDH_DISPATCH_MODEL should be set to NRF_SDH_DISPATCH_MODEL_POLLING  to use nrf_sdh_evts_poll() as suggested

    It is not a must. You can poll the event manually even if you have selected NRF_SDH_DISPATCH_MODEL_APPSH model, but it will only make sense to do so when you know the scheduler queue is not going to be processed. The Softdevice interrupt drives the polling otherwise.

  •  if the problem was caused by the events in the queue not being processed then why does it work after the third reset? shouldn't it be always stuck in that infinite loop?

  • The reason for this is that fstorage is only able to complete one out of the three tasks requested by FDS on initial boot (there is one fstorage operation/task per allocated FDS page). Fstorage processes the tasks queue when receiving flash completion events from the Softdevice.

  • can you please elaborate more on this.
    the code is stuck in an infinite loop waiting for the m_fds_initialized flag.
    how is the FDS event being triggered without calling app_sched_execute();

    thanks

  • fds_init() notifies the application with the FDS_EVT_INIT event right away if all the fds pages have been tagged previously. In this case, the m_fds_initialized flag will get cleared before entering the wait loop. Remember that FDS is able to tag one page on each boot, so the number of resets you need is going to depend on the number of flash pages you have allocated to FDS.

Reply
  • fds_init() notifies the application with the FDS_EVT_INIT event right away if all the fds pages have been tagged previously. In this case, the m_fds_initialized flag will get cleared before entering the wait loop. Remember that FDS is able to tag one page on each boot, so the number of resets you need is going to depend on the number of flash pages you have allocated to FDS.

Children
  • I am seeing the same on SDK16.0.0

    My application is operating with FreeRTOS, so I need to search out a solution here.

    fds_init() occurs after FreeRTOS is running ...

    Not clear the path to solve this problem. I surely don't want a customer to powercycle the product 3 times to force resets ...


    Found a solution ... replaced nrf_delay_ms(50) inside the while() loop, with FreeRTOS friendly vTaskDelay(50)

    This way the FDS_EVT_INIT is able to be returned to the fds_evt_handler()

    This issue only occured on a 'virgin' FDS setup.

Related