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

FreeRTOS power consumption spikes when in System ON sleep mode

Hello -

We are developing on the nRF52840-DK, using SDK 15.3.0 and FreeRTOS with tickless idle. The SoftDevice is disabled. Using the PPK v2.3.1 when our app is in System ON sleep mode, we are seeing power consumption spikes at regular ~1s intervals:

During this period our app is waiting on messages from a FreeRTOS message queue. At this time there are no other pending tasks:

xQueueReceive(msgQueue, &msg, maxDelayMS);

After maxDelayMS we enter System OFF sleep mode and the current drops for the duration:

NRF_POWER->SYSTEMOFF = 1;

I toggle an onboard LED in the vPortSuppressTicksAndSleep() function before and after System ON sleep. The LED toggles only once after the specified delay, which leads me to believe that the sleep logic is working as expected. After some experimentation, I found that the RTC wakeup interrupt configuration leads to the spikes. If I comment out this code, the spikes no longer occur, but of course the app never exits System ON sleep:

/* Configure CTC interrupt */
nrf_rtc_cc_set(portNRF_RTC_REG, 0, wakeupTime);
nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);
nrf_rtc_int_enable(portNRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);

Is there anything we can do in our app or FreeRTOS configuration to eliminate these spikes?

Regards,

Brian

  • That is a worrisome finding. In your application idle hook, you are using both sd_app_evt_wait and WFE. Which one is executed by your application? Are you using logs? can you test once by disabling logs ?(NRF_LOG_ENABLED set to 0 in sdk_config.h file)

  • Susheel -

    Welcome back to this case. In our application idle hook we are calling WFE in the profile I shared three days ago. We do not have NRF_LOG_ENABLED in our build. We do have SOFTDEVICE_PRESENT set to 1 in our build, though this test app isn't using the SoftDevice. Hence the call to nrf_sdh_is_enabled() returns false and we call WFE. The code I shared from the idle hook was basically copied from the SDK vPortSuppressTicksAndSleep() function. Just to clarify, is there anything wrong with this approach?

    That said, I remembered that we have the watch dog timer enabled. In our build we have the NRFX_WDT_CONFIG_BEHAVIOR set to 1 (Run in SLEEP, Pause in HALT). I reverted our code back to use tickless idle, the Nordic vPortSuppressTicksAndSleep() function, but disabled the watch dog timer. That seems to have eliminated the power consumption spikes. The strange thing is that setting the NRFX_WDT_CONFIG_BEHAVIOR to 1, 0, or 8 doesn't eliminate the spikes. Nor does changing the NRFX_WDT_CONFIG_RELOAD_VALUE. Unless the watch dog timer is completely disabled, we see the spikes at ~1s intervals, even if the reload value is much higher.

    I hope these findings help to pin down the root cause. We do want to run with tickless idle and also have the WDT enabled to catch any unexpected stalls while not sleeping. For reference, here is our WDT setup and feed code:

    static nrf_drv_wdt_channel_id wdt_channel_id;
    
    static void watchdog_init(void)
    {
    	nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
    	nrf_drv_clock_lfclk_request(NULL);
    	ret_code_t err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
    	APP_ERROR_CHECK(err_code);
    	nrf_drv_wdt_channel_alloc(&wdt_channel_id);
    	nrf_drv_wdt_enable();
    }
    
    static void watchdog_feed(void)
    {
    	nrf_drv_wdt_feed();
    }
    

    Regards,

    Brian

  • Hello -

    Just a quick check to see if there is anything else we can try here. Another thought I had was to turn off /on the WDT inside vPortSuppressTicksAndSleep() before and after sleep.

    Regards,

    Brian

Related