Thread and Queue not sleeping on NRF51 boards?

24 Nov 2016

Hi,

I've been working with a few simple examples of toggling an LED on and off every second on Mbed OS with a NRF51 DK 1. I've been trying to track down the high power usage with the Mbed OS Eddystone / beacon examples, which have lead me to investigating this without using the BLE stack.

Measuring the voltage differential across a 10ohm resistor that has been installed on the board, I'm reading a 5mAH draw from the device when all the threads should be in a waiting state / queue dispatch has been set to dispatch forever. This is the same consumption as a simple NOP busy wait program toggling the LED on an interrupt.

Is there a reason why queue.dispatch() and all threads waiting (two separate test examples) appear to be busy waiting, rather than putting the board to sleep when there is no work to do?

If I crudely introduce a sleep() in the main thread (trapped in a while) and the addition of dispatch(0) for the dispatch queue example (rather than dispatching forever), then power drops to 0.17mAH for the threaded example and 1.36mAH for the dispatch queue. 0.17mAH appears to be the power consumption for the RTOS ticking over, but the dispatch queue still seems to draw quite an amount (I guess its keeping the CPU awake for longer).

Any pointers to whats going on will be greatly appreciated. Dan

24 Nov 2016

Pastebin examples all using latest mbed OS library.

Interrupt Driven and Sleeping Main Thread: http://pastebin.com/0QFb54TF

Thread version: http://pastebin.com/fp1QS6j2

Event Queue version: http://pastebin.com/UfrGV2iR

25 Nov 2016

After some digging I found the idle task on Mbed OS has sleep(); commented out. By attaching an idle hook callback, I was able to drastically reduce the power consumption on the device (without requiring a thread to constantly call sleep).

Thread::attach_idle_hook(&sleep);

With this, my NRF51 idles at than a 1mA when all threads are in a waiting state. Event loop still uses a lot more (1mA), but is vastly better than busy waiting.

The reason for sleep being commented out in mbed-os/rtos/rtos_idle.c is: /* Sleep: ideally, we should put the chip to sleep. Unfortunately, this usually requires disconnecting the interface chip (debugger). This can be done, but it would break the local file system.

  • /

Dan

25 Nov 2016

The plot thickens. The above still holds true in reducing overall power consumption, but my threaded example was using Mbed OS released on the 30th Sept (the version that as it comes when imported from the online compiler).

As soon as I update past this version, power consumption on the nordic board drastically increases - anyone got an idea what might have changed?

Cheers, Dan

25 Nov 2016

Found reference to the issues: https://github.com/ARMmbed/mbed-os/issues/2769 (mbed OS not sleeping with idle tasks)

and I believe this might be the reason for increased consumption in newer versions of Mbed 5 with NRF51 targets: https://github.com/ARMmbed/mbed-os/issues/2758