Skip to content

DISCO-L475VG-IOT01A wakes up every second #10211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
janjongboom opened this issue Mar 25, 2019 · 22 comments
Closed

DISCO-L475VG-IOT01A wakes up every second #10211

janjongboom opened this issue Mar 25, 2019 · 22 comments

Comments

@janjongboom
Copy link
Contributor

janjongboom commented Mar 25, 2019

Description

This is a power profile of 10 second blinky on DISCO-L475VG-IOT01A. Every second the MCU wakes up. What's going on here?

image

main.cpp

#include "mbed.h"
#include "mbed_stats.h"

static DigitalOut led(LED1);

int main() {
    printf("Hello world!\n");

    while (1) {
        led = !led;
        mbed_stats_cpu_t stats;
        mbed_stats_cpu_get(&stats);
        printf("Uptime: %llu ", stats.uptime / 1000);
        // printf("Idle: %llu ", stats.idle_time);
        printf("Sleep time: %llu ", stats.sleep_time / 1000);
        printf("Deep Sleep: %llu\n", stats.deep_sleep_time / 1000);
        wait_ms(10000);
    }
}

mbed_app.json

{
    "target_overrides": {
        "*": {
            "platform.stdio-convert-newlines": true,
            "platform.cpu-stats-enabled": 1,
            "platform.heap-stats-enabled": 1,
            "platform.sys-stats-enabled": 1,
            "platform.default-serial-baud-rate": 115200,
            "platform.stdio-baud-rate": 115200
        }
    },
    "macros": [
        "MBED_TICKLESS=1",
        "MBED_CONF_TARGET_TICKLESS_FROM_US_TICKER=0",
        "MBED_CONF_APP_IDLE_THREAD_STACK_SIZE=2048"
    ]
}

Mbed OS 5.12 (pre-release) rev. 7dd791e compiled with GCC ARM 6.

Issue request type

[ ] Question
[ ] Enhancement
[X] Bug
@jeromecoutant
Copy link
Collaborator

Hi @janjongboom

Could you try adding
"target.lpticker_lptim_clock": 4
in your mbed_app.json file ?

@jeromecoutant
Copy link
Collaborator

@LMESTM

@LMESTM
Copy link
Contributor

LMESTM commented Mar 25, 2019

This can be related to the maximum timeout period that can be programmed in HW,
Probably the HW Low Power timer cannot sleep for more than about 1sec. So mbed-os scheduler will program it for 1 sec, wake-up, check for anything to be done, then sleep again.

@janjongboom
Copy link
Contributor Author

janjongboom commented Mar 25, 2019

@LMESTM @jeromecoutant Yeah that works indeed! Which brings me to the question on why we aren't using this clock by default. Is there perhaps an application note on picking lpticker clock sources on STM32?

@ciarmcom
Copy link
Member

Internal Jira reference: https://jira.arm.com/browse/MBOCUSTRIA-1057

@elforce
Copy link

elforce commented Jun 10, 2019

Hi gents.
I have the same problem with STM32L432KC target. I wrote about it on the mbed forum 4 months ago but nobody wrote back so I am joining the topic. Below oscillogram with current spikes on STM2L432KC:
DS1Z_QuickPrint1
The results are the same for "target.lpticker_lptim_clock": 1 and 4 so the change from @jeromecoutant does not solve the problem for STM32L432KC.
Time between the spikes are about 1s and the current value is near 1mA. Below my mbed_app.json settings:
{ "config": { "main_stack_size": { "value": 4096 }, "lpticker_lptim": { "value": 4 } }, "target_overrides": { "*": { "platform.stdio-convert-newlines": true, "platform.stdio-baud-rate": 115200, "platform.default-serial-baud-rate": 115200, "platform.stack-stats-enabled": true, "platform.heap-stats-enabled": true, "platform.cpu-stats-enabled": true, "platform.thread-stats-enabled": true, "platform.sys-stats-enabled": true, "lora.public-network" : false, "lora.duty-cycle-on": false, "lora.phy": "EU868", "mbed-trace.enable": true }, "NUCLEO_L432KC": { "target.stdio_uart_tx": "PA_9", "target.stdio_uart_rx": "PA_10" } }, "macros": ["MBEDTLS_USER_CONFIG_FILE=\"mbedtls_lora_config.h\""] }
Program works on LoRaWAN mbed-os example.
Please help to fix it?

@LMESTM
Copy link
Contributor

LMESTM commented Jun 10, 2019

@elforce what do you exactly want to solve ?
mbed-os scheduler relies on the LPTIM counter which wraps-up regularly, at least once per second. The target will wakes-up very shortly then go back to sleep. Is this really an issue ? How much is the power overhead ?

Note: In your above mbed_app.json extract I do not see Jerome recommendation:
"target.lpticker_lptim_clock": 4

@elforce
Copy link

elforce commented Jun 10, 2019

@LMESTM If the device is working on the battery, eg. CR2032, and need to send data every 1 hour then should be in stop mode about 99.9% and wake only to send the data. Waking it up every 1s with mbed-os 5 from stop mode with the cyclical momentary power consumption about 1mA, it will drain the battery quite quickly. My question is how to be in stop mode and have the same behaviour like in mbed 2, static power consumption at the level of a few uA (with peripheries) all time? In mbed-os 5 with ST uC's (I do not know how with others) in stop mode current consumption is not static (tested on STM32L476 and STM32L432). For example about 8 minutes beeing in stop mode with this peaks is equivalent to sending 1 LoRaWAN frame. I think that is a big problem that's why @janjongboom reported it as a Bug.
About "target.lpticker_lptim_clock": 4 and last topic, my fault, I did not include proper code.
Proper is
"config": { "main_stack_size": { "value": 4096 }, "lpticker_lptim_clock": { "value": 4 } },

@LMESTM
Copy link
Contributor

LMESTM commented Jun 10, 2019

@ARMmbed/mbed-os-core this is a question to you - not something specific to STM32. Users are asking for vert long period of Deep Sleep without any wake-ups (RTC alarm like I think).

@elforce
Copy link

elforce commented Jun 10, 2019

I have RTC running in the project and I wake up the device every 30 min, 1h, 3h. There is no problem with that. Probably this 1s awakening are needed for the mbed-os itself so that it can validate events or other stuff. @ARMmbed/mbed-os-core even if it can not be turned off, how this 1s peaks time can be extended?

@LMESTM
Copy link
Contributor

LMESTM commented Jun 10, 2019

@elforce Out of curiosity, what RTC alarm API are you using ?

@elforce
Copy link

elforce commented Jun 10, 2019

It should not matter because I did tests without and with supported RTC. I am using mbed-os rtc_api functions: rtc_read() and rtc_write() but to set Timer and Alarm I use my own functions written using HAL libraries.
On the mbed forum similar threads with awakening every 1s have already been raised 2 or 3 times. In this forum is also a similar thread
https://os.mbed.com/questions/85125/Whats-causing-this-power-spike/
Nobody has given a solution yet, even a partial one. I have tested all.

@LMESTM
Copy link
Contributor

LMESTM commented Jun 10, 2019

It should not matter because I did tests without and with supported RTC. I am using mbed-os rtc_api functions: rtc_read() and rtc_write() but to set Timer and Alarm I use my own functions written using HAL libraries.

That was my point. As of now, there is no standard MBED API in case you want to sleep for hours without any wake-up.

On the mbed forum similar threads with awakening every 1s have already been raised 2 or 3 times. In this forum is also a similar thread
https://os.mbed.com/questions/85125/Whats-causing-this-power-spike/
Nobody has given a solution yet, even a partial one. I have tested all.

The 1sec wake-up is due to the wrap-around of the 16 bits LPTIM HW in STM32. Scheduler relies on this continuous always-running clock and will always schedule next interrupt within a few seconds to count for the next wrap-up. So as long as RTC is not used, you will have wake-ups every seconds or so.
The only solution I would see is to have an official RTC API is to be able to enter some 'standby mode', i.e. the scheduler would not schedule anything anymore until next wake-up from RTC ....
Maybe you could use a service like osKernelSuspend(); to disable the wake-ups and osKernelResume(0); from Alarm ... but I don't know if this is safe or not.

@elforce
Copy link

elforce commented Jun 10, 2019

Internally for the mbed-os operation, the system does not use the RTC clock and there is probably a problem here. Although my overwrites and reconfigures the RTC, the peak problem still exists every 1s.
It is a good starting point with osKernelSuspend(). This function occurs in the mbed code about 10 times, so the mbed-os uses it. Maybe someone from @mbed-os will write how to suspend and resume safely mbed-os with LPTIM. That would solve the problem.
When device is in shutdown mode (also own code on HAL libs) the problem does not exist but shutdown is not good because it cuts off the power supply from the bank 1 RAM and I lose the initialized LoRa stack and I have to do the join every time I exit the shutdown.

@elforce
Copy link

elforce commented Jun 10, 2019

Calling osKernelSuspend () does not work. Maybe I do not comply with conditions to stop the Kernel scheduler.

@LMESTM
Copy link
Contributor

LMESTM commented Jun 10, 2019

@MarceloSalazar - in case you can help.

@jeromecoutant
Copy link
Collaborator

Hi

Should we keep this issue opened on ST side ?

Calling osKernelSuspend () does not work. Maybe I do not comply with conditions to stop the Kernel scheduler.

@bulislaw @kjbracey-arm

Thx

@LMESTM
Copy link
Contributor

LMESTM commented Oct 15, 2019

I agree that this is not st specific.
Is it possible for an application to suspend the Kernel in order to avoid regular wake-ups and rely only other-than-timer related interrupts for waking-up and then resume the Kernel ?

@kjbracey
Copy link
Contributor

kjbracey commented Oct 16, 2019

Should we keep this issue opened on ST side ?

Don't think so. My input:

Suspending the kernel does not in itself do anything to stop the timer. Normally when the kernel is suspended, we want the timer to carry on running, so we know how long we were asleep for.

Therefore in this case the device wakes up periodically to note the timer wrap. (Or to run any other scheduled events). This would be less of a problem on a chip with a slower-wrapping timer.

If you really want to stay asleep in this scenario, then you will need to mask off the interrupts you don't want - have a limited set of "wake" interrupts.

This is something we're planning to do - have a "system suspend" that masks off all interrupts except a specific set, then calls kernel suspend.

You can experiment with this sort of thing yourself. As of 5.14 you can do this

bool want_wake;

void my_wake_irq_handler()
{
    want_wake = true;
}

bool do_i_need_to_wake(void *)
{
     return want_wake;
}

void system_suspend()
{
      osKernelSuspend();
      // reprogram NVIC to mask all interrupts apart from your wake interrupt here
      mbed::internal::do_untimed_sleep(do_i_need_to_wake, nullptr);
      // restore original NVIC mask here
      osKernelResume(0);
}

There are a bunch of tricky race issues there (eg what if someone else is messing with interrupt masks after we record it - might not restore it accurately), but basic concept should force the system down.

If we wanted to time the sleep we have more work to do - we'd want to stop the LPTIM and instead time it with the RTC. (And maybe use RTC as a wakeup source). Getting that all done smoothly and neatly and generically is a work package, but for a local app you can kind of do whatever you need manually.

@jeromecoutant
Copy link
Collaborator

Should we keep this issue opened on ST side ?
Don't think so. My input:

Maybe, you should then remove the "device st" label,
and assign the issue to core team ?
Thx

@0xc0170
Copy link
Contributor

0xc0170 commented Sep 21, 2020

we closed the issue as we have feature request for this being tracked separately.

@janjongboom
Copy link
Contributor Author

For anyone running into this, I put together a quick standby example for STM32 on Mbed OS some years ago: https://github.com/janjongboom/stm32-standby-rtc-wakeup

@ciarmcom ciarmcom removed the mirrored label Dec 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants