Merge pull request #11203 from Tharazi97/Watchdog_lower_limit_timeout_test

Add watchdog lower limit timeout test
pull/11779/head
Martin Kojtal 2019-10-31 14:25:52 +01:00 committed by GitHub
commit eea83007be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 140 additions and 6 deletions

View File

@ -24,9 +24,16 @@
#include "us_ticker_api.h"
#include "utest/utest.h"
#include "watchdog_timing_tests.h"
#include "mbed.h"
#define TIMEOUT_LOWER_LIMIT_MS 1000ULL
// A window to allow to process watchdog kick before timeout occurs.
#define TIME_WINDOW_MS 2UL
#define MSG_VALUE_DUMMY "0"
#define CASE_DATA_INVALID 0xffffffffUL
#define CASE_DATA_PHASE2_OK 0xfffffffeUL
#define MSG_VALUE_LEN 24
#define MSG_KEY_LEN 24
@ -34,6 +41,7 @@
#define MSG_KEY_DEVICE_READY "ready"
#define MSG_KEY_START_CASE "start_case"
#define MSG_KEY_HEARTBEAT "hb"
#define MSG_KEY_DEVICE_RESET "dev_reset"
using utest::v1::Case;
using utest::v1::Specification;
@ -47,6 +55,18 @@ struct testcase_data {
testcase_data current_case;
bool send_reset_notification(testcase_data *tcdata, uint32_t delay_ms)
{
char msg_value[12];
int str_len = snprintf(msg_value, sizeof msg_value, "%02x,%08lx", tcdata->start_index + tcdata->index, delay_ms);
if (str_len != (sizeof msg_value) - 1) {
utest_printf("Failed to compose a value string to be sent to host.");
return false;
}
greentea_send_kv(MSG_KEY_DEVICE_RESET, msg_value);
return true;
}
template<uint32_t timeout_ms>
void test_timing()
{
@ -110,6 +130,48 @@ void test_timing()
}
}
void test_timeout_lower_limit()
{
watchdog_features_t features = hal_watchdog_get_platform_features();
if (TIMEOUT_LOWER_LIMIT_MS > features.max_timeout) {
TEST_IGNORE_MESSAGE("Requested timeout value not supported for this target -- ignoring test case.");
return;
}
// Phase 2. -- verify the test results.
if (current_case.received_data != CASE_DATA_INVALID) {
TEST_ASSERT_EQUAL(CASE_DATA_PHASE2_OK, current_case.received_data);
current_case.received_data = CASE_DATA_INVALID;
return;
}
// Phase 1. -- run the test code.
watchdog_config_t config = { TIMEOUT_LOWER_LIMIT_MS };
uint32_t sleep_time_ms = (TIMEOUT_LOWER_LIMIT_MS * features.clock_typical_frequency / features.clock_max_frequency) - TIME_WINDOW_MS;
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
// Kick watchdog before timeout.
// Watchdog should not trigger before timeout * clock accuracy.
// If device restarts while waiting for the kick, test fails.
wait_us(sleep_time_ms * 1000);
hal_watchdog_kick();
if (send_reset_notification(&current_case, 2 * TIMEOUT_LOWER_LIMIT_MS) == false) {
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
return;
}
hal_watchdog_kick();
// Watchdog should fire before twice the timeout value.
wait_us(2 * TIMEOUT_LOWER_LIMIT_MS * 1000);
// Watchdog reset should have occurred during that wait() 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.");
}
utest::v1::status_t case_setup(const Case *const source, const size_t index_of_case)
{
current_case.index = index_of_case;
@ -151,6 +213,7 @@ Case cases[] = {
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>),
Case("timeout accuracy", case_setup, test_timeout_lower_limit)
};
Specification specification((utest::v1::test_setup_handler_t) testsuite_setup, cases);

View File

@ -40,6 +40,16 @@
template<uint32_t timeout_ms, uint32_t delta_ms>
void test_timing();
/** Test Watchdog timeout
*
* Given a device with a Watchdog started,
* when the Watchdog timout doesn't expire,
* then the device restart is not performed.
* When the Watchdog timout does expire,
* then the device is restarted after the timeout and before twice the timeout value.
*/
void test_timeout_lower_limit();
#endif
#endif

View File

@ -47,7 +47,9 @@
* already initialized the hardware watchdog timer.
* * Maximum supported timeout is `UINT32_MAX` milliseconds; minimum timeout
* is 1 millisecond.
* * The watchdog should trigger at or after the timeout value.
* * The uncalibrated watchdog should trigger at or after the timeout value
* multiplied by the frequency accuracy ratio of its oscillator (typical_frequency / max_frequency).
* * The calibrated watchdog should trigger at or after the timeout value.
* * The watchdog should trigger before twice the timeout value.
*
* # Undefined behavior
@ -99,6 +101,14 @@ typedef struct {
* You can stop the watchdog after it starts without a reset.
*/
bool disable_watchdog;
/**
* Typical frequency of not calibrated watchdog clock in Hz.
*/
uint32_t clock_typical_frequency;
/**
* Maximum frequency of not calibrated watchdog clock in Hz.
*/
uint32_t clock_max_frequency;
} watchdog_features_t;

View File

@ -67,9 +67,11 @@ uint32_t hal_watchdog_get_reload_value(void)
watchdog_features_t hal_watchdog_get_platform_features(void)
{
watchdog_features_t features = {
/* .max_timeout = */ cyhal_wdt_get_max_timeout_ms(),
/* .update_config = */ true,
/* .disable_watchdog = */ true
/* .max_timeout = */ cyhal_wdt_get_max_timeout_ms(),
/* .update_config = */ true,
/* .disable_watchdog = */ true,
/* .clock_typical_frequency = */ 32000,
/* .clock_max_frequency = */ 36100
};
return features;
}

View File

@ -123,6 +123,8 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
features.max_timeout = MAX_TIMEOUT_MS;
features.update_config = true;
features.disable_watchdog = true;
features.clock_typical_frequency = 1000;
features.clock_max_frequency = 1111;
return features;
}

View File

@ -125,6 +125,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
wdt_feat.update_config = 1;
/* Support stopping watchdog timer */
wdt_feat.disable_watchdog = 1;
/* Accuracy of watchdog timer */
wdt_feat.clock_typical_frequency = 10000;
wdt_feat.clock_max_frequency = 15000;
return wdt_feat;
}

View File

@ -124,6 +124,10 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
wdt_feat.update_config = 1;
/* Support stopping watchdog timer */
wdt_feat.disable_watchdog = 1;
/* Accuracy of watchdog timer */
wdt_feat.clock_typical_frequency = 10000;
wdt_feat.clock_max_frequency = 15000;
return wdt_feat;
}

View File

@ -130,6 +130,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
wdt_feat.update_config = 1;
/* Support stopping watchdog timer */
wdt_feat.disable_watchdog = 1;
/* Accuracy of watchdog timer */
wdt_feat.clock_typical_frequency = 10000;
wdt_feat.clock_max_frequency = 15000;
return wdt_feat;
}

View File

@ -124,6 +124,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
wdt_feat.update_config = 1;
/* Support stopping watchdog timer */
wdt_feat.disable_watchdog = 1;
/* Accuracy of watchdog timer */
wdt_feat.clock_typical_frequency = 10000;
wdt_feat.clock_max_frequency = 14000;
return wdt_feat;
}

View File

@ -63,6 +63,8 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
features.max_timeout = ((float)INT32_MAX/clk)*1000;
features.update_config = true;
features.disable_watchdog = false;
features.clock_typical_frequency = 4000000;
features.clock_max_frequency = 4040000;
return features;
}

View File

@ -103,7 +103,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
const watchdog_features_t features = {
.max_timeout = WDT_MAX_TIMEOUT_MS,
.update_config = WDT_CAN_UPDATE,
.disable_watchdog = WDT_CAN_STOP
.disable_watchdog = WDT_CAN_STOP,
.clock_typical_frequency = 36000,
.clock_max_frequency = 47000
};
return features;

View File

@ -123,6 +123,24 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
features.max_timeout = MAX_TIMEOUT_MS;
features.update_config = true;
features.disable_watchdog = false;
/* STM32 IWDG (Independent Watchdog) is clocked by its own dedicated low-speed clock (LSI) */
features.clock_typical_frequency = LSI_VALUE;
/* See LSI oscillator characteristics in Data Sheet */
#if defined(STM32F1)
features.clock_max_frequency = 60000;
#elif defined(STM32L0) || defined(STM32L1)
features.clock_max_frequency = 56000;
#elif defined(STM32F2) || defined(STM32F4) || defined(STM32F7)
features.clock_max_frequency = 47000;
#elif defined(STM32F0) || defined(STM32F3)
features.clock_max_frequency = 50000;
#elif defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
features.clock_max_frequency = 33600;
#else
#error "unsupported target"
#endif
return features;
}

View File

@ -92,7 +92,19 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
watchdog_features_t feat = {
.max_timeout = 262145,
.update_config = true,
.disable_watchdog = true
.disable_watchdog = true,
#if defined(TARGET_EFM32GG) || defined(TARGET_EFM32HG) || defined(TARGET_EFM32LG) || defined(TARGET_EFM32WG) || defined(TARGET_EFM32ZG)
.clock_typical_frequency = 1000,
.clock_max_frequency = 1750
#elif defined(TARGET_EFM32GG11)
.clock_typical_frequency = 1000,
.clock_max_frequency = 1120
#elif defined(TARGET_EFM32PG) || defined(TARGET_EFM32PG12) || defined(TARGET_EFR32MG1) || defined(TARGET_EFR32MG12)
.clock_typical_frequency = 1000,
.clock_max_frequency = 1070
#else
#error "unsupported target"
#endif
};
return feat;
}