Skip to content
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

Timeout & LowPowerTimeout tests #5106

Merged
merged 1 commit into from
Mar 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 48 additions & 107 deletions TESTS/mbed_drivers/lp_timeout/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,138 +15,79 @@
*/

#if !DEVICE_LOWPOWERTIMER
#error [NOT_SUPPORTED] Low power timer not supported for this target
#error [NOT_SUPPORTED] Low power timer not supported for this target
#endif

#include "mbed.h"
#include "greentea-client/test_env.h"
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"

#include "mbed.h"
#include "../timeout/timeout_tests.h"

using namespace utest::v1;

volatile static bool complete;
static LowPowerTimeout lpt;

/* Timeouts are quite arbitrary due to large number of boards with varying level of accuracy */
#define LONG_TIMEOUT (100000)
#define SHORT_TIMEOUT (600)

void cb_done() {
complete = true;
}

#if DEVICE_SLEEP
void lp_timeout_1s_deepsleep(void)
utest::v1::status_t greentea_failure_handler(const Case * const source, const failure_t reason)
{
complete = false;
LowPowerTimer timer;

/*
* Since deepsleep() may shut down the UART peripheral, we wait for 10ms
* to allow for hardware serial buffers to completely flush.

* This should be replaced with a better function that checks if the
* hardware buffers are empty. However, such an API does not exist now,
* so we'll use the wait_ms() function for now.
*/
wait_ms(10);

/*
* We use here the low power timer instead of microsecond timer for start and
* end because the microseconds timer might be disable during deepsleep.
*/
timer.start();
lpt.attach(&cb_done, 1);
/* Make sure deepsleep is allowed, to go to deepsleep */
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
sleep();
while (!complete);

/* It takes longer to wake up from deep sleep */
TEST_ASSERT_UINT32_WITHIN(LONG_TIMEOUT, 1000000, timer.read_us());
TEST_ASSERT_TRUE(complete);
greentea_case_failure_abort_handler(source, reason);
return STATUS_CONTINUE;
}

void lp_timeout_1s_sleep(void)
{
complete = false;
Timer timer;
timer.start();

sleep_manager_lock_deep_sleep();
lpt.attach(&cb_done, 1);
bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed");
sleep();
while (!complete);
sleep_manager_unlock_deep_sleep();

TEST_ASSERT_UINT32_WITHIN(LONG_TIMEOUT, 1000000, timer.read_us());
TEST_ASSERT_TRUE(complete);
}
#endif /* DEVICE_SLEEP */
Case cases[] = {
Case("Callback called once (attach)", test_single_call<AttachTester<LowPowerTimeout> >),
Case("Callback called once (attach_us)", test_single_call<AttachUSTester<LowPowerTimeout> >),

void lp_timeout_us(uint32_t delay_us, uint32_t tolerance)
{
complete = false;
Timer timer;
timer.start();
Case("Callback not called when cancelled (attach)", test_cancel<AttachTester<LowPowerTimeout> >),
Case("Callback not called when cancelled (attach_us)", test_cancel<AttachUSTester<LowPowerTimeout> >),

lpt.attach_us(&cb_done, delay_us);
while (!complete);
Case("Callback override (attach)", test_override<AttachTester<LowPowerTimeout> >),
Case("Callback override (attach_us)", test_override<AttachUSTester<LowPowerTimeout> >),

/* Using RTC which is less accurate */
TEST_ASSERT_UINT32_WITHIN(tolerance, delay_us, timer.read_us());
TEST_ASSERT_TRUE(complete);
}
Case("Multiple timeouts running in parallel (attach)", test_multiple<AttachTester<LowPowerTimeout> >),
Case("Multiple timeouts running in parallel (attach_us)", test_multiple<AttachUSTester<LowPowerTimeout> >),

void lp_timeout_5s(void)
{
lp_timeout_us(5000000, LONG_TIMEOUT);
}
Case("Zero delay (attach)", test_no_wait<AttachTester<LowPowerTimeout> >),
Case("Zero delay (attach_us)", test_no_wait<AttachUSTester<LowPowerTimeout> >),

void lp_timeout_1s(void)
{
lp_timeout_us(1000000, LONG_TIMEOUT);
}
Case("10 ms delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>,
greentea_failure_handler),
Case("10 ms delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>,
greentea_failure_handler),

void lp_timeout_1ms(void)
{
lp_timeout_us(1000, SHORT_TIMEOUT);
}
Case("1 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),

void lp_timeout_500us(void)
{
lp_timeout_us(500, SHORT_TIMEOUT);

}
Case("5 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("5 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>,
greentea_failure_handler),

utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) {
greentea_case_failure_abort_handler(source, reason);
return STATUS_CONTINUE;
}

Case cases[] = {
Case("500us LowPowerTimeout", lp_timeout_500us, greentea_failure_handler),
Case("1ms LowPowerTimeout", lp_timeout_1ms, greentea_failure_handler),
Case("1sec LowPowerTimeout", lp_timeout_1s, greentea_failure_handler),
Case("5sec LowPowerTimeout", lp_timeout_5s, greentea_failure_handler),
#if DEVICE_SLEEP
Case("1sec LowPowerTimeout from sleep", lp_timeout_1s_sleep, greentea_failure_handler),
Case("1sec LowPowerTimeout from deepsleep", lp_timeout_1s_deepsleep, greentea_failure_handler),
#endif /* DEVICE_SLEEP */
Case("1 s delay during sleep (attach)", test_sleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay during sleep (attach_us)", test_sleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),

Case("1 s delay during deepsleep (attach)", test_deepsleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay during deepsleep (attach_us)", test_deepsleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
#endif

Case("Timing drift (attach)", test_drift<AttachTester<LowPowerTimeout> >),
Case("Timing drift (attach_us)", test_drift<AttachUSTester<LowPowerTimeout> >),
};

utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(20, "default_auto");
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(240, "timing_drift_auto");
return greentea_test_setup_handler(number_of_cases);
}

Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);

int main() {
int main()
{
Harness::run(specification);
}
108 changes: 50 additions & 58 deletions TESTS/mbed_drivers/timeout/main.cpp
Original file line number Diff line number Diff line change
@@ -1,91 +1,83 @@
/*
* Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


/*
* Tests is to measure the accuracy of Timeout over a period of time
*
*
* 1) DUT would start to update callback_trigger_count every milli sec
* 2) Host would query what is current count base_time, Device responds by the callback_trigger_count
* 3) Host after waiting for measurement stretch. It will query for device time again final_time.
* 4) Host computes the drift considering base_time, final_time, transport delay and measurement stretch
* 5) Finally host send the results back to device pass/fail based on tolerance.
* 6) More details on tests can be found in timing_drift_auto.py
*
*/

#include "mbed.h"
#include "greentea-client/test_env.h"
#include "utest/utest.h"
#include "unity/unity.h"
#include "timeout_tests.h"

using namespace utest::v1;

#define PERIOD_US 10000

volatile int ticker_count = 0;
volatile uint32_t callback_trigger_count = 0;
static const int test_timeout = 240;
Timeout timeout;

void set_incremeant_count() {
timeout.attach_us(set_incremeant_count, PERIOD_US);
++callback_trigger_count;
utest::v1::status_t greentea_failure_handler(const Case * const source, const failure_t reason)
{
greentea_case_failure_abort_handler(source, reason);
return STATUS_CONTINUE;
}

void test_case_timeout() {
Case cases[] = {
Case("Callback called once (attach)", test_single_call<AttachTester<Timeout> >),
Case("Callback called once (attach_us)", test_single_call<AttachUSTester<Timeout> >),

char _key[11] = { };
char _value[128] = { };
int expected_key = 1;
uint8_t results_size = 0;
Case("Callback not called when cancelled (attach)", test_cancel<AttachTester<Timeout> >),
Case("Callback not called when cancelled (attach_us)", test_cancel<AttachUSTester<Timeout> >),

greentea_send_kv("timing_drift_check_start", 0);
timeout.attach_us(set_incremeant_count, PERIOD_US);
Case("Callback override (attach)", test_override<AttachTester<Timeout> >),
Case("Callback override (attach_us)", test_override<AttachUSTester<Timeout> >),

// wait for 1st signal from host
do {
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
expected_key = strcmp(_key, "base_time");
} while (expected_key);
Case("Multiple timeouts running in parallel (attach)", test_multiple<AttachTester<Timeout> >),
Case("Multiple timeouts running in parallel (attach_us)", test_multiple<AttachUSTester<Timeout> >),

greentea_send_kv(_key, callback_trigger_count * PERIOD_US);
Case("Zero delay (attach)", test_no_wait<AttachTester<Timeout> >),
Case("Zero delay (attach_us)", test_no_wait<AttachUSTester<Timeout> >),

// wait for 2nd signal from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
greentea_send_kv(_key, callback_trigger_count * PERIOD_US);
Case("10 ms delay accuracy (attach)", test_delay_accuracy<AttachTester<Timeout>, 10000, SHORT_DELTA_US>,
greentea_failure_handler),
Case("10 ms delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<Timeout>, 10000, SHORT_DELTA_US>,
greentea_failure_handler),

//get the results from host
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
Case("1 s delay accuracy (attach)", test_delay_accuracy<AttachTester<Timeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<Timeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),

TEST_ASSERT_EQUAL_STRING_MESSAGE("pass", _key,"Host side script reported a fail...");
}
Case("5 s delay accuracy (attach)", test_delay_accuracy<AttachTester<Timeout>, 5000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("5 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<Timeout>, 5000000, LONG_DELTA_US>,
greentea_failure_handler),

#if DEVICE_SLEEP
Case("1 s delay during sleep (attach)", test_sleep<AttachTester<Timeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
Case("1 s delay during sleep (attach_us)", test_sleep<AttachUSTester<Timeout>, 1000000, LONG_DELTA_US>,
greentea_failure_handler),
#endif

// Test casess
Case cases[] = { Case("Timers: toggle on/off", test_case_timeout), };
Case("Timing drift (attach)", test_drift<AttachTester<Timeout> >),
Case("Timing drift (attach_us)", test_drift<AttachUSTester<Timeout> >),
};

utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(test_timeout, "timing_drift_auto");
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(240, "timing_drift_auto");
return greentea_test_setup_handler(number_of_cases);
}

Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);

int main() {
int main()
{
Harness::run(specification);
}
Loading