-
Notifications
You must be signed in to change notification settings - Fork 26
Description
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.
mbed-os/targets/TARGET_STM/sleep.c
Lines 265 to 273 in 9ce9f38
/* 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.