ARMmbed / mbed-os

Arm Mbed OS is a platform operating system designed for the internet of things
https://mbed.com
Other
4.67k stars 2.98k forks source link

EventScheduler consumes 2milliAmps on Nrf51 #8133

Closed pjsf1000 closed 3 years ago

pjsf1000 commented 6 years ago

Description

With v.simple main function I have measure 2ma on a simple NRf dev board.
I am using the online compiler with MbedOS 5.9.7

static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE);

int main()
{  
    eventQueue.dispatch_forever();
    while (true) {
        Thread::wait(60000);
    }

    return 0;
}

Issue request type

[ ] Question
[ ] Enhancement
[x] Bug

pan- commented 6 years ago

@geky @maciejbocianski Any idea of what may be going on ?

We got 20uA power consumption with the following code:

int main()
{  
    while (true) {
        Thread::wait(60000);
    }

    return 0;
}
maciejbocianski commented 6 years ago

@pan- I assume that 20uA is OK, and the question is about eventQueue utilization?

pjsf1000 commented 6 years ago

That’s correct. More concerned about event queue as the priority.

On Mon, 17 Sep 2018 at 08:01, Maciej Bociański notifications@github.com wrote:

@pan- https://github.com/pan- I assume that 20uA is OK, and the question is about eventQueue utilization?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/ARMmbed/mbed-os/issues/8133#issuecomment-421908818, or mute the thread https://github.com/notifications/unsubscribe-auth/AnS_m7PPzrUgLIKG1hqwL9zFO0KFsAOYks5ub0i3gaJpZM4WpEkn .

--


Peter Ferguson Cambridge

pan- commented 6 years ago

@maciejbocianski The event queue does nothing, the only executed code is eventQueue.dispatch_forever(); and no events are injected into the event queue.

I think it may be related to a clock issue.

maciejbocianski commented 6 years ago

@pjsf1000 @pan- I tested following code on 5.9.7 source and get following results In operate 4.7mA and for both Thread::wait(20000); and eventQueue.dispatch_forever(); 4uA

run command: mbed compile -t GCC_ARM -m nrf51_dk -v --profile develop -f

#include "mbed.h"

static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE);

#define TEST_SLEEP
//#define TEST_WAIT_EVENT

void fun1()
{
    eventQueue.break_dispatch();
}

int main()
{
    volatile uint32_t counter = 10000000;
    while(counter--);
#ifdef TEST_SLEEP
    Thread::wait(20000);
#endif
#ifdef TEST_WAIT_EVENT
    LowPowerTimeout lpt;
    lpt.attach_us(fun1, 20000000);
    eventQueue.dispatch_forever();
#endif  
    counter = 1000000000;
    while(counter--);
}
#endif
TacoGrandeTX commented 6 years ago

I have a feeling this is related to a mask which is used to prevent WFE from executing: https://github.com/ARMmbed/mbed-os/issues/5647. Let me make a PR and you can test.

TacoGrandeTX commented 6 years ago

@pjsf1000 - Here is the PR: https://github.com/ARMmbed/mbed-os/pull/8224

pan- commented 6 years ago

So we solved the issue. It is not related to #8224 nor the event queue on mbed-os 5.10 (other versions may have their own issues). Turns out the arm compiler is at fault here as it initialised the default serial port before main.

We validated that assumption by making get_console return NULL instead of initialising the serial port then the power consumption dropped to acceptable levels.

That issue is not observed on other compilers.

@c1728p9 Any idea how we can improve the retarget code to solve that issue ?

0xc0170 commented 6 years ago

So we solved the issue. It is not related to #8224 nor the event queue on mbed-os 5.10 (other versions may have their own issues). Turns out the arm compiler is at fault here as it initialised the default serial port before main.

I recall this issue in earlier versions. This is related https://github.com/ARMmbed/mbed-os/pull/2466 (we looked previously at this and ARMCC is different as noted). Previously was fixed by lazy initialization that was breaking. As retarget and filehandles were refactored, we might find something better this time 🤞

c1728p9 commented 6 years ago

Just creating a serial port or console object shouldn't increase current draw. The uart (and its high current draw) should only be active under the following conditions:

  1. Data is being synchronously written to serial port/console - serial_putc
  2. *Data is being synchronously read from a serial port/console - serial_getc
    • Some applications actually expected the serial receiver to be always enabled when the CPU isn't sleeping. In these applications there is typically super loop which polls serial_readable before calling serial_getc to prevent blocking. Having the uart on whent he CPU is on should't be a problem though since the majority of the uart's current draw is caused from the main clock being turned on, which the core requires anyway.
  3. Serial port/console is asynchronously waiting for or transferring data - serial_irq_set

From what I recall, the NRF5x's hardware automatically determines if the main clock can be turned off during sleep (and thus bringing current down to the microamp range) based on which tasks have been started. When a task which require the high frequency clock is running, such as UART RX and TX, it prevent the high frequency clock from being turned off during sleep.

The current implementation of serial_init start both the TX and RX tasks unconditionally. If these tasks are instead running only when they are needed then the serial port could be used normally without the downside of high current draw.

Possible solution:

adbridge commented 6 years ago

Internal Jira reference: https://jira.arm.com/browse/IOTDEV-1641

0xc0170 commented 3 years ago

There were couple of updates (serial enable/disable input), also nrf51 was removed from in 6.0 as I recall. It's still on 5.15 branch so if the issue persists there, the new ticket with updated information is required.

@pan- shall this be still opened (it will need to be tested on different platform and armclang) ?

pan- commented 3 years ago

I think it can be closed as the target has been removed. A new ticket for 5.15 would have to be opened.

ciarmcom commented 3 years ago

We closed this issue because it has been inactive for quite some time and we believe it to be low priority. If you think that the priority should be higher, then please reopen with your justification for increasing the priority.