From 69ba9ec916ec499ba5939387e9baa5c49b57b075 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Thu, 12 Sep 2019 14:27:12 +0200 Subject: [PATCH 01/12] Add clock_typical_frequency and clock_max_frequency to watchdog api --- hal/watchdog_api.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hal/watchdog_api.h b/hal/watchdog_api.h index 4bb41d533f..603e529085 100644 --- a/hal/watchdog_api.h +++ b/hal/watchdog_api.h @@ -99,6 +99,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; From 36d010d7967156d41c8ed39a8bcdb9da247b15e1 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Mon, 2 Sep 2019 09:59:23 +0200 Subject: [PATCH 02/12] Add watchdog lower limit timeout test --- TESTS/mbed_hal/watchdog_timing/main.cpp | 63 +++++++++++++++++++ .../watchdog_timing/watchdog_timing_tests.h | 10 +++ 2 files changed, 73 insertions(+) diff --git a/TESTS/mbed_hal/watchdog_timing/main.cpp b/TESTS/mbed_hal/watchdog_timing/main.cpp index 816fb889e7..fef8db76b0 100644 --- a/TESTS/mbed_hal/watchdog_timing/main.cpp +++ b/TESTS/mbed_hal/watchdog_timing/main.cpp @@ -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 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. + + ThisThread::sleep_for(sleep_time_ms); + 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. + ThisThread::sleep_for(2 * TIMEOUT_LOWER_LIMIT_MS); + + // 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); diff --git a/TESTS/mbed_hal/watchdog_timing/watchdog_timing_tests.h b/TESTS/mbed_hal/watchdog_timing/watchdog_timing_tests.h index 0e768207ee..e85fdebf79 100644 --- a/TESTS/mbed_hal/watchdog_timing/watchdog_timing_tests.h +++ b/TESTS/mbed_hal/watchdog_timing/watchdog_timing_tests.h @@ -40,6 +40,16 @@ template 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 From cb5311654cf2f470ef2b6018f918a1401a4c8369 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Thu, 12 Sep 2019 09:16:11 +0200 Subject: [PATCH 03/12] Add watchdog clock accuracy to Cypress targets. --- targets/TARGET_Cypress/TARGET_PSOC6/cy_watchdog_api.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_Cypress/TARGET_PSOC6/cy_watchdog_api.c b/targets/TARGET_Cypress/TARGET_PSOC6/cy_watchdog_api.c index 523a47ccb1..d20cf825d7 100644 --- a/targets/TARGET_Cypress/TARGET_PSOC6/cy_watchdog_api.c +++ b/targets/TARGET_Cypress/TARGET_PSOC6/cy_watchdog_api.c @@ -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; } From 632098de94963b0e37a464adfd0aa8697b15f96a Mon Sep 17 00:00:00 2001 From: int_szyk Date: Thu, 12 Sep 2019 09:16:45 +0200 Subject: [PATCH 04/12] Add watchdog clock accuracy to NXP targets. --- targets/TARGET_NXP/TARGET_LPC176X/watchdog_api.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/TARGET_NXP/TARGET_LPC176X/watchdog_api.c b/targets/TARGET_NXP/TARGET_LPC176X/watchdog_api.c index 40172d6e76..496284a493 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/watchdog_api.c +++ b/targets/TARGET_NXP/TARGET_LPC176X/watchdog_api.c @@ -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; } From c7dfa87bbf3d0a9e6a2df5ee5d0eb6bd4b033420 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Wed, 18 Sep 2019 14:45:05 +0200 Subject: [PATCH 05/12] Add watchdog clock accuracy to ONSEMI targets. --- targets/TARGET_ONSEMI/TARGET_NCS36510/watchdog_api.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/targets/TARGET_ONSEMI/TARGET_NCS36510/watchdog_api.c b/targets/TARGET_ONSEMI/TARGET_NCS36510/watchdog_api.c index 02c98c71f7..6f899496b4 100644 --- a/targets/TARGET_ONSEMI/TARGET_NCS36510/watchdog_api.c +++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/watchdog_api.c @@ -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; From 82e595269314b4efd420e983bc470c091db10c49 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Thu, 12 Sep 2019 09:17:50 +0200 Subject: [PATCH 06/12] Add watchdog clock accuracy to Freescale targets. --- .../TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/watchdog_api.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/watchdog_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/watchdog_api.c index 1b2f72feb4..5de8ffd5df 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/watchdog_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/watchdog_api.c @@ -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; } From f892ae7f1ec5c451faf523b186fb2343ca2f8362 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Wed, 11 Sep 2019 10:59:03 +0200 Subject: [PATCH 07/12] Add watchdog clock accuracy to STM targets. --- targets/TARGET_STM/watchdog_api.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/targets/TARGET_STM/watchdog_api.c b/targets/TARGET_STM/watchdog_api.c index bcbb5df152..eb0f1141d0 100644 --- a/targets/TARGET_STM/watchdog_api.c +++ b/targets/TARGET_STM/watchdog_api.c @@ -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; } From e2955eb968cf0a9825b89c7516745c92c88b77c4 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Wed, 11 Sep 2019 15:00:40 +0200 Subject: [PATCH 08/12] Add watchdog clock accuracy to SiliconLabs targets --- .../TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c b/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c index 72a64a99d6..28e5233f2b 100644 --- a/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c @@ -93,6 +93,18 @@ watchdog_features_t hal_watchdog_get_platform_features(void) .max_timeout = 262145, .update_config = 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; } From d68a802f074321406a3da4a97d7eeff36919780d Mon Sep 17 00:00:00 2001 From: int_szyk Date: Wed, 11 Sep 2019 15:54:51 +0200 Subject: [PATCH 09/12] Add watchdog clock accuracy to Nuvoton targets. --- targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c | 3 +++ targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c | 4 ++++ targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c | 3 +++ targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c | 3 +++ 4 files changed, 13 insertions(+) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c index 9bc73d2266..cf54a405d2 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c @@ -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; } diff --git a/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c index 96150ae7e7..a61bb6909e 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c @@ -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; } diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c index 376d2cb639..288e9367fb 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c @@ -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; } diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c index 96150ae7e7..01fb436b2e 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c @@ -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; } From b54222adf1ad31dcba3562e415d73b8b6b270ee8 Mon Sep 17 00:00:00 2001 From: int_szyk Date: Thu, 26 Sep 2019 13:52:16 +0200 Subject: [PATCH 10/12] Change assumptions of watchdog_api. --- hal/watchdog_api.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hal/watchdog_api.h b/hal/watchdog_api.h index 603e529085..222361102e 100644 --- a/hal/watchdog_api.h +++ b/hal/watchdog_api.h @@ -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 From fe685068ff6a206b487abf3e4bde612140ab4b07 Mon Sep 17 00:00:00 2001 From: Filip Jagodzinski Date: Tue, 15 Oct 2019 15:40:10 +0200 Subject: [PATCH 11/12] Silicon Labs: Fix watchdog features build errors --- .../TARGET_EFM32/watchdog_api.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c b/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c index 28e5233f2b..37dbdaca59 100644 --- a/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c @@ -92,16 +92,16 @@ 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; + .clock_typical_frequency = 1000, + .clock_max_frequency = 1750 #elif defined(TARGET_EFM32GG11) - .clock_typical_frequency = 1000; - .clock_max_frequency = 1120; + .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; + .clock_typical_frequency = 1000, + .clock_max_frequency = 1070 #else #error "unsupported target" #endif From 5dcd0f7aec72812770af28bf84e8668c37931476 Mon Sep 17 00:00:00 2001 From: Filip Jagodzinski Date: Wed, 30 Oct 2019 16:00:28 +0100 Subject: [PATCH 12/12] Prevent sleep during watchdog lower limit test --- TESTS/mbed_hal/watchdog_timing/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TESTS/mbed_hal/watchdog_timing/main.cpp b/TESTS/mbed_hal/watchdog_timing/main.cpp index fef8db76b0..9f0e75bc42 100644 --- a/TESTS/mbed_hal/watchdog_timing/main.cpp +++ b/TESTS/mbed_hal/watchdog_timing/main.cpp @@ -154,7 +154,7 @@ void test_timeout_lower_limit() // Watchdog should not trigger before timeout * clock accuracy. // If device restarts while waiting for the kick, test fails. - ThisThread::sleep_for(sleep_time_ms); + wait_us(sleep_time_ms * 1000); hal_watchdog_kick(); if (send_reset_notification(¤t_case, 2 * TIMEOUT_LOWER_LIMIT_MS) == false) { @@ -164,7 +164,7 @@ void test_timeout_lower_limit() hal_watchdog_kick(); // Watchdog should fire before twice the timeout value. - ThisThread::sleep_for(2 * TIMEOUT_LOWER_LIMIT_MS); + wait_us(2 * TIMEOUT_LOWER_LIMIT_MS * 1000); // Watchdog reset should have occurred during that wait() above;