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

nRF52840, SDK 14.0.0 and tickless idle FreeRTOS - some suggestions

This post is more about some suggestions for review rather than a question.

I've been looking at implementing a project using the nRF52840, SDK 14.0.0 and FreeRTOS in a low power application. The release note for SDK 14.0.0. indicates that FreeRTOS is not supported on the nRF52840, however I see no reason why FreeRTOS shouldn't work on this platform.

I ported the example ble_app_hrs_freertos app for ARM GCC to pca10056 and found that current consumption was very high even with tickless idle enabled. Upon profiling the idle code, I found that sd_app_event_wait() was being called and then exiting immediately on every iteration of the idle loop.

There were what seemed to be a number of improvements that could be made. Please see the attached port_cmsis_systick.c files for my suggested changes.

They include:

  • Don't turn off app interrupts when going into idle. Instead only turn off RTC timing interrupts. This should improve interrupt latency while sleeping since interrupt handlers will run directly after return from WFE events. This also allows interrupt handlers to make FreeRTOS API calls which could potentially set tasks to running.
  • Stay as long as possible in the inner tickless idle loop if there is no reason to exit. That is, the only reason to exit idle is if a task has been scheduled to run, or the maximum time to wait has elapsed.
  • Don't rely solely on RTC capture compare interrupt to wake from WFE. Instead, use a counter comparison check to determine if wait time has elapsed.
  • Clear pending CPU event using SEV/WFE before testing for idle exit and going to sleep. This prevents any event prior to going to idle from waking the CPU immediately on a call to sd_app_event_wait().

There are likely some improvements to make to this code, however I have found that these changes result in a significant reduction in consumed power.

The attached port_cmsis_systick_with_profiling.c contains a set of counters which are ticked at various points of the idle loop to try and gain an understanding of how often events occur. eg We can determine how often the code requests idle, how many times we wake CPU from idle but the conditions for FreeRTOS are not met to exit idle (eg as a result of a BLE interrupt).

I'd be interested in feedback on this approach and to know if there are any holes in my reasoning with the proposed changes.

I've attached the ble_app_hrs_freertos app ported to pca10056. This also includes an FPU_IRQHandler to address issues with CPU not sleeping with FPU interrupt pending.

ble_app_hrs_freertos_pca10056.tgz

port_cmsis_systick_with_profiling.c

port_cmsis_systick.c

UPDATED 16th Oct 2018:

See the updated port_cmsis_systick.c which includes important changes including the following:

  • Fixes a bug which could result in infinite sleep in idle.  Ensure that pending RTC wake interrupt is cleared before entry to sleep.
  • Ensures pending FPU interrupts are cleared before entry to sleep.
  • Support GPIO profiling of time spent asleep.  Use critical section around WFE instruction when profiling to ensure that GPIO pins are set to show CPU asleep/awake state prior to interrupt handlers running.

  • nRF52832 on both Custom board and the DK using S132. Compiled with GCC. HRS freeRTOS example from the SDK. Measurements with Rigol multimeter.

  • Hi there I also working on tickless topics. May I know what was the current consumption value for non tickless vs tickless for rRF52832 which you managed to get from your board? Thanks.

  • Hi Ing,

    A quick test with SDK15.2 on PCA10056 DK with ble_app_hrs_freertos example gives me these results while advertising

    1) Tickless IDLE enabled ~700uA

    2) Tickless IDLE disable and forever looking with sd_app_evt_wait() in vApplicationIdleHook gives around ~920uA while advertising.

  • Hi Austin!

    Great work! With your code current consumption on my nRF52832 custom board dropped from 1 mA to 0,1 mA.

  • Thanks for posting your current consumption statistics, that's a great result.

1 2 3 4 5