mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #11203 from Tharazi97/Watchdog_lower_limit_timeout_test
Add watchdog lower limit timeout testpull/11779/head
commit
eea83007be
|
@ -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(¤t_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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue