Skip to content
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
9 changes: 5 additions & 4 deletions TESTS/mbed_drivers/reset_reason/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

#define MSG_VALUE_WATCHDOG_STATUS "wdg_present"
#define WDG_TIMEOUT_MS 50UL
#define WDG_TIMEOUT_DELTA_MS 50UL

#else
#define MSG_VALUE_WATCHDOG_STATUS "no_wdg"
Expand All @@ -50,6 +49,8 @@
#define MSG_KEY_RESET_REASON "reason"
#define MSG_KEY_DEVICE_RESET "reset"

#define SERIAL_FLUSH_TIME_MS 20

typedef enum {
CMD_STATUS_CONTINUE,
CMD_STATUS_ERROR
Expand Down Expand Up @@ -91,7 +92,7 @@ static cmd_status_t handle_command(const char *key, const char *value)

if (strcmp(key, MSG_KEY_DEVICE_RESET) == 0 && strcmp(value, MSG_VALUE_DEVICE_RESET_NVIC) == 0) {
greentea_send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_ACK);
wait_ms(10); // Wait for the serial buffers to flush.
wait_ms(SERIAL_FLUSH_TIME_MS); // Wait for the serial buffers to flush.
NVIC_SystemReset();
TEST_ASSERT_MESSAGE(0, "NVIC_SystemReset did not reset the device as expected.");
return CMD_STATUS_ERROR;
Expand All @@ -100,13 +101,13 @@ static cmd_status_t handle_command(const char *key, const char *value)
#if DEVICE_WATCHDOG
if (strcmp(key, MSG_KEY_DEVICE_RESET) == 0 && strcmp(value, MSG_VALUE_DEVICE_RESET_WATCHDOG) == 0) {
greentea_send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_ACK);
wait_ms(10); // Wait for the serial buffers to flush.
wait_ms(SERIAL_FLUSH_TIME_MS); // Wait for the serial buffers to flush.
watchdog_config_t config = { .timeout_ms = WDG_TIMEOUT_MS };
if (hal_watchdog_init(&config) != WATCHDOG_STATUS_OK) {
TEST_ASSERT_MESSAGE(0, "hal_watchdog_init() error.");
return CMD_STATUS_ERROR;
}
wait_ms(WDG_TIMEOUT_MS + WDG_TIMEOUT_DELTA_MS);
wait_ms(2 * WDG_TIMEOUT_MS); // Watchdog should fire before twice the timeout value.
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
return CMD_STATUS_ERROR;
}
Expand Down
3 changes: 1 addition & 2 deletions TESTS/mbed_hal/reset_reason/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

#define MSG_VALUE_WATCHDOG_STATUS "wdg_present"
#define WDG_TIMEOUT_MS 50UL
#define WDG_TIMEOUT_DELTA_MS 50UL

#else
#define MSG_VALUE_WATCHDOG_STATUS "no_wdg"
Expand Down Expand Up @@ -115,7 +114,7 @@ static cmd_status_t handle_command(const char *key, const char *value)
TEST_ASSERT_MESSAGE(0, "hal_watchdog_init() error.");
return CMD_STATUS_ERROR;
}
wait_ms(WDG_TIMEOUT_MS + WDG_TIMEOUT_DELTA_MS);
wait_ms(2 * WDG_TIMEOUT_MS); // Watchdog should fire before twice the timeout value.
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
return CMD_STATUS_ERROR;
}
Expand Down
64 changes: 39 additions & 25 deletions TESTS/mbed_hal/watchdog/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,12 @@

#include <stdlib.h>

/* This is platform specific and depends on the watchdog timer implementation,
* e.g. STM32F4 uses 32kHz internal RC oscillator to clock the IWDG, so
* when the prescaler divider is set to max value of 256 the resolution
* drops to 8 ms.
*/
#define WORST_TIMEOUT_RESOLUTION_MS 8UL

#define TIMEOUT_DELTA_MS (WORST_TIMEOUT_RESOLUTION_MS)
/* The shortest timeout value, this test suite is able to handle correctly. */
#define WDG_MIN_TIMEOUT_MS 50UL

// Do not set watchdog timeout shorter than 50 ms as it may cause the
// host-test-runner return 'TIMEOUT' instead of 'FAIL' / 'PASS' if watchdog
// performs reset during test suite teardown.
// Do not set watchdog timeout shorter than WDG_MIN_TIMEOUT_MS, as it may
// cause the host-test-runner return 'TIMEOUT' instead of 'FAIL' / 'PASS'
// if watchdog performs reset during test suite teardown.
#define WDG_TIMEOUT_MS 100UL

#define MSG_VALUE_DUMMY "0"
Expand Down Expand Up @@ -115,7 +109,7 @@ void test_stop()
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&WDG_CONFIG_DEFAULT));
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_stop());
// Make sure that a disabled watchdog does not reset the core.
wait_ms(WDG_TIMEOUT_MS + TIMEOUT_DELTA_MS);
wait_ms(2 * WDG_TIMEOUT_MS); // Watchdog should fire before twice the timeout value.

TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_stop());
}
Expand All @@ -129,16 +123,27 @@ void test_update_config()
}

watchdog_config_t config = WDG_CONFIG_DEFAULT;
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
TEST_ASSERT_UINT32_WITHIN(WORST_TIMEOUT_RESOLUTION_MS, config.timeout_ms, hal_watchdog_get_reload_value());

config.timeout_ms = features.max_timeout - 2 * WORST_TIMEOUT_RESOLUTION_MS;
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
TEST_ASSERT_UINT32_WITHIN(WORST_TIMEOUT_RESOLUTION_MS, config.timeout_ms, hal_watchdog_get_reload_value());

config.timeout_ms = features.max_timeout;
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
TEST_ASSERT_UINT32_WITHIN(WORST_TIMEOUT_RESOLUTION_MS, config.timeout_ms, hal_watchdog_get_reload_value());
uint32_t timeouts[] = {
features.max_timeout / 4,
features.max_timeout / 8,
features.max_timeout / 16
};
int num_timeouts = sizeof timeouts / sizeof timeouts[0];

for (size_t i = 0; i < num_timeouts; i++) {
if (timeouts[i] < WDG_MIN_TIMEOUT_MS) {
TEST_IGNORE_MESSAGE("Requested timeout value is too short -- ignoring test case.");
return;
}

config.timeout_ms = timeouts[i];
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
uint32_t reload_value = hal_watchdog_get_reload_value();
// The watchdog should trigger at, or after the timeout value.
TEST_ASSERT(reload_value >= timeouts[i]);
// The watchdog should trigger before twice the timeout value.
TEST_ASSERT(reload_value < 2 * timeouts[i]);
}
}

utest::v1::status_t case_setup_sync_on_reset(const Case *const source, const size_t index_of_case)
Expand Down Expand Up @@ -186,17 +191,26 @@ utest::v1::status_t case_teardown_wdg_stop_or_reset(const Case *const source, co
template<uint32_t timeout_ms>
void test_init()
{
watchdog_config_t config = { timeout_ms };
if (timeout_ms < WDG_MIN_TIMEOUT_MS) {
TEST_IGNORE_MESSAGE("Requested timeout value is too short -- ignoring test case.");
return;
}
watchdog_config_t config = { .timeout_ms = timeout_ms };
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
TEST_ASSERT_UINT32_WITHIN(WORST_TIMEOUT_RESOLUTION_MS, timeout_ms, hal_watchdog_get_reload_value());
uint32_t reload_value = hal_watchdog_get_reload_value();
// The watchdog should trigger at, or after the timeout value.
TEST_ASSERT(reload_value >= timeout_ms);
// The watchdog should trigger before twice the timeout value.
TEST_ASSERT(reload_value < 2 * timeout_ms);
}

void test_init_max_timeout()
{
watchdog_features_t features = hal_watchdog_get_platform_features();
watchdog_config_t config = { .timeout_ms = features.max_timeout };
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
TEST_ASSERT_UINT32_WITHIN(WORST_TIMEOUT_RESOLUTION_MS, features.max_timeout, hal_watchdog_get_reload_value());
// The watchdog should trigger at, or after the timeout value.
TEST_ASSERT(hal_watchdog_get_reload_value() >= features.max_timeout);
}

int testsuite_setup_sync_on_reset(const size_t number_of_cases)
Expand Down
26 changes: 8 additions & 18 deletions TESTS/mbed_hal/watchdog/watchdog_api_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,22 @@ void test_stop();

/** Test Watchdog init multiple times
*
* Given @a max_timeout value returned by @a hal_watchdog_get_platform_features():
*
* Given @a config.timeout_ms is set to WDG_TIMEOUT_MS,
* when @a hal_watchdog_init() is called,
* then @a WATCHDOG_STATUS_OK is returned
* and @a hal_watchdog_get_reload_value() returns WDG_TIMEOUT_MS.
*
* Given @a config.timeout_ms is set to max_timeout-delta,
* when @a hal_watchdog_init() is called,
* then @a WATCHDOG_STATUS_OK is returned
* and @a hal_watchdog_get_reload_value() returns max_timeout-delta.
*
* Given @a config.timeout_ms is set to max_timeout,
* when @a hal_watchdog_init() is called,
* then @a WATCHDOG_STATUS_OK is returned
* and @a hal_watchdog_get_reload_value() returns max_timeout.
* Given a set of unique timeout values,
* when @a config.timeout_ms is set to each of these values (T),
* then, for every value T, @a hal_watchdog_init() returns @a WATCHDOG_STATUS_OK
* and @a hal_watchdog_get_reload_value() returns a reload value R
* and T <= R < 2 * T.
*/
void test_update_config();

/** Test Watchdog init with a valid config
*
* Given @a config.timeout_ms is set to X ms,
* Given @a config.timeout_ms is set to T ms,
* which is within supported Watchdog timeout range,
* when @a hal_watchdog_init() is called,
* then @a WATCHDOG_STATUS_OK is returned
* and @a hal_watchdog_get_reload_value() returns X.
* and @a hal_watchdog_get_reload_value() returns a reload value R
* and T <= R < 2 * T.
*/
template<uint32_t timeout_ms>
void test_init();
Expand Down
54 changes: 26 additions & 28 deletions TESTS/mbed_hal/watchdog_reset/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,8 @@
#include "watchdog_reset_tests.h"
#include "mbed.h"

#if TARGET_NUMAKER_PFM_NANO130
/* On NUMAKER_PFM_NANO130 target, WDT's clock source is fixed to LIRC, which is more
* inaccurate than other targets. Enlarge this delta define to pass this test. */
#define TIMEOUT_MS 500UL
#define TIMEOUT_DELTA_MS 100UL
#else
#define TIMEOUT_MS 100UL
#define TIMEOUT_DELTA_MS 10UL
#endif
#define KICK_ADVANCE_MS 10UL

#define MSG_VALUE_DUMMY "0"
#define CASE_DATA_INVALID 0xffffffffUL
Expand Down Expand Up @@ -103,12 +96,13 @@ void test_simple_reset()
// Phase 1. -- run the test code.
// Init the watchdog and wait for a device reset.
watchdog_config_t config = { TIMEOUT_MS };
if (send_reset_notification(&current_case, TIMEOUT_MS + TIMEOUT_DELTA_MS) == false) {
if (send_reset_notification(&current_case, 2 * TIMEOUT_MS) == false) {
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
return;
}
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
wait_ms(TIMEOUT_MS + TIMEOUT_DELTA_MS); // Device reset expected.
// Watchdog should fire before twice the timeout value.
wait_ms(2 * TIMEOUT_MS); // Device reset expected.

// Watchdog reset should have occurred during wait_ms() above;

Expand All @@ -130,23 +124,22 @@ void test_sleep_reset()
watchdog_config_t config = { TIMEOUT_MS };
Semaphore sem(0, 1);
Timeout timeout;
if (send_reset_notification(&current_case, TIMEOUT_MS + TIMEOUT_DELTA_MS) == false) {
if (send_reset_notification(&current_case, 2 * TIMEOUT_MS) == false) {
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
return;
}
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
sleep_manager_lock_deep_sleep();
timeout.attach_us(mbed::callback(release_sem, &sem), 1000ULL * (TIMEOUT_MS + TIMEOUT_DELTA_MS));
// Watchdog should fire before twice the timeout value.
timeout.attach_us(mbed::callback(release_sem, &sem), 1000ULL * (2 * TIMEOUT_MS));
if (sleep_manager_can_deep_sleep()) {
TEST_ASSERT_MESSAGE(0, "Deepsleep should be disallowed.");
return;
}
while (sem.wait(0) != 1) {
sleep(); // Device reset expected.
}
sem.wait(); // Device reset expected.
sleep_manager_unlock_deep_sleep();

// Watchdog reset should have occurred during sleep() above;
// Watchdog reset should have occurred during sem.wait() (sleep) above;

hal_watchdog_kick(); // Just to buy some time for testsuite failure handling.
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
Expand All @@ -166,21 +159,20 @@ void test_deepsleep_reset()
watchdog_config_t config = { TIMEOUT_MS };
Semaphore sem(0, 1);
LowPowerTimeout lp_timeout;
if (send_reset_notification(&current_case, TIMEOUT_MS + TIMEOUT_DELTA_MS) == false) {
if (send_reset_notification(&current_case, 2 * TIMEOUT_MS) == false) {
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
return;
}
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
lp_timeout.attach_us(mbed::callback(release_sem, &sem), 1000ULL * (TIMEOUT_MS + TIMEOUT_DELTA_MS));
// Watchdog should fire before twice the timeout value.
lp_timeout.attach_us(mbed::callback(release_sem, &sem), 1000ULL * (2 * TIMEOUT_MS));
wait_ms(SERIAL_FLUSH_TIME_MS); // Wait for the serial buffers to flush.
if (!sleep_manager_can_deep_sleep()) {
TEST_ASSERT_MESSAGE(0, "Deepsleep should be allowed.");
}
while (sem.wait(0) != 1) {
sleep(); // Device reset expected.
}
sem.wait(); // Device reset expected.

// Watchdog reset should have occurred during that sleep() above;
// Watchdog reset should have occurred during sem.wait() (deepsleep) above;

hal_watchdog_kick(); // Just to buy some time for testsuite failure handling.
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
Expand Down Expand Up @@ -209,14 +201,17 @@ void test_restart_reset()
wait_ms(TIMEOUT_MS / 2UL);
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_stop());
// Check that stopping the Watchdog prevents a device reset.
wait_ms(TIMEOUT_MS / 2UL + TIMEOUT_DELTA_MS);
// The watchdog should trigger at, or after the timeout value.
// The watchdog should trigger before twice the timeout value.
wait_ms(TIMEOUT_MS / 2UL + TIMEOUT_MS);

if (send_reset_notification(&current_case, TIMEOUT_MS + TIMEOUT_DELTA_MS) == false) {
if (send_reset_notification(&current_case, 2 * TIMEOUT_MS) == false) {
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
return;
}
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
wait_ms(TIMEOUT_MS + TIMEOUT_DELTA_MS); // Device reset expected.
// Watchdog should fire before twice the timeout value.
wait_ms(2 * TIMEOUT_MS); // Device reset expected.

// Watchdog reset should have occurred during that wait() above;

Expand All @@ -237,14 +232,17 @@ void test_kick_reset()
watchdog_config_t config = { TIMEOUT_MS };
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
for (int i = 3; i; i--) {
wait_ms(TIMEOUT_MS / 2UL);
// The reset is prevented as long as the watchdog is kicked
// anytime before the timeout.
wait_ms(TIMEOUT_MS - KICK_ADVANCE_MS);
hal_watchdog_kick();
}
if (send_reset_notification(&current_case, TIMEOUT_MS + TIMEOUT_DELTA_MS) == false) {
if (send_reset_notification(&current_case, 2 * TIMEOUT_MS) == false) {
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
return;
}
wait_ms(TIMEOUT_MS + TIMEOUT_DELTA_MS); // Device reset expected.
// Watchdog should fire before twice the timeout value.
wait_ms(2 * TIMEOUT_MS); // Device reset expected.

// Watchdog reset should have occurred during that wait() above;

Expand Down
20 changes: 13 additions & 7 deletions TESTS/mbed_hal/watchdog_timing/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct testcase_data {

testcase_data current_case;

template<uint32_t timeout_ms, uint32_t delta_ms>
template<uint32_t timeout_ms>
void test_timing()
{
watchdog_features_t features = hal_watchdog_get_platform_features();
Expand All @@ -57,9 +57,15 @@ void test_timing()
}

// Phase 2. -- verify the test results.
// Verify the heartbeat time span sent by host is within given delta.
// Verify the heartbeat time span sent by host is within given range:
// 1. The watchdog should trigger at, or after the timeout value.
// 2. The watchdog should trigger before twice the timeout value.
if (current_case.received_data != CASE_DATA_INVALID) {
TEST_ASSERT_UINT32_WITHIN(delta_ms, timeout_ms, current_case.received_data);
// Provided the watchdog works as expected, the last timestamp received
// by the host will always be before the expected reset time. Because
// of that, the constraint no 1. is not verified.
TEST_ASSERT(current_case.received_data > 0);
TEST_ASSERT(current_case.received_data < 2 * timeout_ms);
current_case.received_data = CASE_DATA_INVALID;
return;
}
Expand Down Expand Up @@ -141,10 +147,10 @@ int testsuite_setup(const size_t number_of_cases)
}

Case cases[] = {
Case("Timing, 200 ms", case_setup, test_timing<200UL, 55UL>),
Case("Timing, 500 ms", case_setup, test_timing<500UL, 130UL>),
Case("Timing, 1000 ms", case_setup, test_timing<1000UL, 255UL>),
Case("Timing, 3000 ms", case_setup, test_timing<3000UL, 380UL>),
Case("Timing, 200 ms", case_setup, test_timing<200UL>),
Case("Timing, 500 ms", case_setup, test_timing<500UL>),
Case("Timing, 1000 ms", case_setup, test_timing<1000UL>),
Case("Timing, 3000 ms", case_setup, test_timing<3000UL>),
};

Specification specification((utest::v1::test_setup_handler_t) testsuite_setup, cases);
Expand Down
4 changes: 2 additions & 2 deletions TESTS/mbed_hal/watchdog_timing/watchdog_timing_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
*
* Phase 2.
* Given a device restarted by the watchdog timer,
* when the device receives time measurement from the host,
* then time measured by host equals X ms.
* when the device receives time measurement T from the host,
* then X <= T < 2 * X.
*/
template<uint32_t timeout_ms, uint32_t delta_ms>
void test_timing();
Expand Down
Loading