Skip to content

The recovery time from deep sleep of STM32U5 is too slow #482

@wdx04

Description

@wdx04

Last year, when I was adding support for NUCLEO-U545RE-Q and NUCLEO-U5A5ZJ-Q boards, there are 3 failed tests (#273). The reason for the failure is that it takes too long to recover from deep sleep mode.

Here is a simplified version of a Greentea LowPowerTimeout test. When running the test on a STM32U5 target, it will print "error try_acquire #2" in the console. To pass the test I have to increase the TEST_LATENCY from 2ms to 10ms.

#include "mbed.h"
#include <atomic>
EventQueue queue;

const chrono::milliseconds TEST_DELAY = 10ms;
const chrono::milliseconds TEST_LATENCY = 2ms;
uint32_t start_time, end_time;
std:: atomic_bool called = false;

void sem_callback(Semaphore *sem)
{
    sem->release();
    called = true;
}

template<typename T>
void test_single_call(void)
{
    Semaphore sem(0, 1);
    T timeout;

    start_time = osKernelGetTickCount();

    timeout.attach(mbed::callback(sem_callback, &sem), TEST_DELAY);

    bool acquired = sem.try_acquire();
    if(acquired) printf("error try_acquire #1\n");

    acquired = sem.try_acquire_for(TEST_DELAY + TEST_LATENCY);
    end_time = osKernelGetTickCount();
    if(!acquired) printf("error try_acquire #2\n");

    acquired = sem.try_acquire_for(TEST_DELAY + TEST_LATENCY);
    if(acquired) printf("error try_acquire #3\n");

    timeout.detach();

    if(called)
    {
        printf("Interval: %lu ms.\n", end_time - start_time);
    }
    else
    {
        printf("sem_callback not called!\n");
    }
}

int main()
{
    printf("Application started!\n");
    test_single_call<LowPowerTimeout>();
    queue.dispatch_forever();
    return 0;
}

But if I comment out the calls to ForceOscOutofDeepSleep() and ForcePeriphOutofDeepSleep() here, the recovery time can be significantly reduced. After this modification, the above test can be passed with TEST_LATENCY = 2ms, and the previously failed 3 Greentea tests are all passable.

/* We've seen unstable PLL CLK configuration when DEEP SLEEP exits just few µs after being entered
* So we need to force clock init out of Deep Sleep.
* This init has been split into 2 separate functions so that the involved structures are not allocated on the stack in parallel.
* This will reduce the maximum stack usage in case on non-optimized / debug compilers settings.
*/
ForceOscOutofDeepSleep();
ForcePeriphOutofDeepSleep();
SetSysClock();
#endif

The question now is whether it is safe to comment out these two function calls, or if there is a better way to solve this problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions