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 Reply Children
  • ble_app_hts.zip

    Hi Vidar,

    I got involved in other development work and So I'm replying bit late. 

    I have attached a project (ble_app_hts.zip) which is having the same 3 power cycle issue. 

    You can extract the ble_app_hts folder and place it in SDK_ROOT/examples/ and use the segger project.

    FYI:

    I'm using App Scheduler in the application and so I have set the macro NRF_SDH_DISPATCH_MODEL to 1 i.e. NRF_SDH_DISPATCH_MODEL_APPSH. And I had used sd_app_evt_wait() in wait_for_fds_ready(). 

    Now when I use nrf_sdh_evts_poll() instead of sd_app_evt_wait() , the issue is solved.

    As per my understanding, the Softdevice events were being scheduled using app_scheduler and sd_app_evt_wait() expects SoftDevice events in interrupt context. And maybe because of that, the application couldn't come out of wait_for_fds_ready(). Whereas nrf_sdh_evts_poll() continuously polls for events and is able to capture the event.

    Please, let me know if this fix and my reasoning are correct. I would like to know if there is any other fix to this. Also, it would be great if you could explain the behavior observed. 

    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 at https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.0.0%2Fgroup__nrf__sdh.html 

  • 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

Related