mirror of https://github.com/ARMmbed/mbed-os.git
Update deep sleep lock check in tests
When the define LPTICKER_DELAY_TICKS is set deep sleep can be randomly disallowed when using the low power ticker. This is because a Timer object, which locks deep sleep, is used to protect from back-to-back writes to lp tickers which can't support that. This causes tests which assert that deep sleep is allowed to intermittently fail. To fix this intermittent failure this patch adds the function sleep_manager_can_deep_sleep_test_check() which checks if deep sleep is allowed over a duration. It updates all the tests to use sleep_manager_can_deep_sleep_test_check() rather than sleep_manager_can_deep_sleep() so the tests work even if deep sleep is spuriously blocked.pull/7524/head
parent
1bbf43ad38
commit
472ababfef
|
@ -29,90 +29,90 @@ using namespace utest::v1;
|
|||
|
||||
void deep_sleep_lock_lock_test()
|
||||
{
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Check basic usage works
|
||||
DeepSleepLock lock;
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Check that unlock and lock change can deep sleep as expected
|
||||
DeepSleepLock lock;
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
|
||||
lock.unlock();
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
lock.lock();
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Check that unlock releases sleep based on count
|
||||
DeepSleepLock lock;
|
||||
lock.lock();
|
||||
lock.lock();
|
||||
lock.unlock();
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Check that unbalanced locks do not leave deep sleep locked
|
||||
DeepSleepLock lock;
|
||||
lock.lock();
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
|
||||
}
|
||||
|
||||
void timer_lock_test()
|
||||
{
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Just creating a timer object does not lock sleep
|
||||
Timer timer;
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Starting a timer does lock sleep
|
||||
Timer timer;
|
||||
timer.start();
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(false, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Stopping a timer after starting it allows sleep
|
||||
Timer timer;
|
||||
timer.start();
|
||||
timer.stop();
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Starting a timer multiple times still lets you sleep
|
||||
Timer timer;
|
||||
timer.start();
|
||||
timer.start();
|
||||
}
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
{
|
||||
// Stopping a timer multiple times still lets you sleep
|
||||
Timer timer;
|
||||
timer.start();
|
||||
timer.stop();
|
||||
timer.stop();
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_EQUAL(true, sleep_manager_can_deep_sleep_test_check());
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
|
|
|
@ -263,7 +263,7 @@ void test_sleep(void)
|
|||
timer.start();
|
||||
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us);
|
||||
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed");
|
||||
while (sem.wait(0) != 1) {
|
||||
sleep();
|
||||
|
@ -322,7 +322,7 @@ void test_deepsleep(void)
|
|||
timer.start();
|
||||
timeout.attach_callback(mbed::callback(sem_callback, &sem), delay_us);
|
||||
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
|
||||
while (sem.wait(0) != 1) {
|
||||
sleep();
|
||||
|
|
|
@ -130,7 +130,7 @@ void lp_ticker_deepsleep_test()
|
|||
* tick_count + TICKER_INT_VAL. */
|
||||
lp_ticker_set_interrupt(tick_count + TICKER_INT_VAL);
|
||||
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check());
|
||||
|
||||
while (!intFlag) {
|
||||
sleep();
|
||||
|
|
|
@ -74,7 +74,7 @@ void rtc_sleep_test_support(bool deepsleep_mode)
|
|||
|
||||
timeout.attach(callback, DELAY_4S);
|
||||
|
||||
TEST_ASSERT(sleep_manager_can_deep_sleep() == deepsleep_mode);
|
||||
TEST_ASSERT(sleep_manager_can_deep_sleep_test_check() == deepsleep_mode);
|
||||
|
||||
while (!expired) {
|
||||
sleep();
|
||||
|
|
|
@ -25,15 +25,15 @@ using namespace utest::v1;
|
|||
|
||||
void sleep_manager_deepsleep_counter_test()
|
||||
{
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_TRUE(deep_sleep_allowed);
|
||||
|
||||
sleep_manager_lock_deep_sleep();
|
||||
deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_FALSE(deep_sleep_allowed);
|
||||
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_TRUE(deep_sleep_allowed);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ void sleep_manager_multithread_test()
|
|||
t2.join();
|
||||
}
|
||||
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ void sleep_manager_irq_test()
|
|||
timer.stop();
|
||||
}
|
||||
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
|
||||
}
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ void test_deepsleep(void)
|
|||
|
||||
lptimer.start();
|
||||
st.schedule_tick(TEST_TICKS);
|
||||
TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "Deep sleep should be allowed");
|
||||
TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep_test_check(), "Deep sleep should be allowed");
|
||||
while (st.sem_wait(0) != 1) {
|
||||
sleep();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "mbed_error.h"
|
||||
#include "mbed_debug.h"
|
||||
#include "mbed_stats.h"
|
||||
#include "us_ticker_api.h"
|
||||
#include "lp_ticker_api.h"
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
@ -183,6 +184,19 @@ bool sleep_manager_can_deep_sleep(void)
|
|||
return deep_sleep_lock == 0 ? true : false;
|
||||
}
|
||||
|
||||
bool sleep_manager_can_deep_sleep_test_check()
|
||||
{
|
||||
const uint32_t check_time_us = 2000;
|
||||
const ticker_data_t *const ticker = get_us_ticker_data();
|
||||
uint32_t start = ticker_read(ticker);
|
||||
while ((ticker_read(ticker) - start) < check_time_us) {
|
||||
if (sleep_manager_can_deep_sleep()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void sleep_manager_sleep_auto(void)
|
||||
{
|
||||
#ifdef MBED_SLEEP_TRACING_ENABLED
|
||||
|
|
|
@ -122,6 +122,17 @@ void sleep_manager_unlock_deep_sleep_internal(void);
|
|||
*/
|
||||
bool sleep_manager_can_deep_sleep(void);
|
||||
|
||||
/** Check if the target can deep sleep within a period of time
|
||||
*
|
||||
* This function in intended for use in testing. The amount
|
||||
* of time this functions waits for deeps sleep to be available
|
||||
* is currently 2ms. This may change in the future depending
|
||||
* on testing requirements.
|
||||
*
|
||||
* @return true if a target can go to deepsleep, false otherwise
|
||||
*/
|
||||
bool sleep_manager_can_deep_sleep_test_check(void);
|
||||
|
||||
/** Enter auto selected sleep mode. It chooses the sleep or deeepsleep modes based
|
||||
* on the deepsleep locking counter
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue