Skip to content

Commit eea8300

Browse files
authored
Merge pull request #11203 from Tharazi97/Watchdog_lower_limit_timeout_test
Add watchdog lower limit timeout test
2 parents 50abaa6 + 5dcd0f7 commit eea8300

File tree

13 files changed

+140
-6
lines changed

13 files changed

+140
-6
lines changed

TESTS/mbed_hal/watchdog_timing/main.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,24 @@
2424
#include "us_ticker_api.h"
2525
#include "utest/utest.h"
2626
#include "watchdog_timing_tests.h"
27+
#include "mbed.h"
28+
29+
#define TIMEOUT_LOWER_LIMIT_MS 1000ULL
30+
31+
// A window to allow to process watchdog kick before timeout occurs.
32+
#define TIME_WINDOW_MS 2UL
2733

2834
#define MSG_VALUE_DUMMY "0"
2935
#define CASE_DATA_INVALID 0xffffffffUL
36+
#define CASE_DATA_PHASE2_OK 0xfffffffeUL
3037

3138
#define MSG_VALUE_LEN 24
3239
#define MSG_KEY_LEN 24
3340

3441
#define MSG_KEY_DEVICE_READY "ready"
3542
#define MSG_KEY_START_CASE "start_case"
3643
#define MSG_KEY_HEARTBEAT "hb"
44+
#define MSG_KEY_DEVICE_RESET "dev_reset"
3745

3846
using utest::v1::Case;
3947
using utest::v1::Specification;
@@ -47,6 +55,18 @@ struct testcase_data {
4755

4856
testcase_data current_case;
4957

58+
bool send_reset_notification(testcase_data *tcdata, uint32_t delay_ms)
59+
{
60+
char msg_value[12];
61+
int str_len = snprintf(msg_value, sizeof msg_value, "%02x,%08lx", tcdata->start_index + tcdata->index, delay_ms);
62+
if (str_len != (sizeof msg_value) - 1) {
63+
utest_printf("Failed to compose a value string to be sent to host.");
64+
return false;
65+
}
66+
greentea_send_kv(MSG_KEY_DEVICE_RESET, msg_value);
67+
return true;
68+
}
69+
5070
template<uint32_t timeout_ms>
5171
void test_timing()
5272
{
@@ -110,6 +130,48 @@ void test_timing()
110130
}
111131
}
112132

133+
void test_timeout_lower_limit()
134+
{
135+
watchdog_features_t features = hal_watchdog_get_platform_features();
136+
if (TIMEOUT_LOWER_LIMIT_MS > features.max_timeout) {
137+
TEST_IGNORE_MESSAGE("Requested timeout value not supported for this target -- ignoring test case.");
138+
return;
139+
}
140+
141+
// Phase 2. -- verify the test results.
142+
if (current_case.received_data != CASE_DATA_INVALID) {
143+
TEST_ASSERT_EQUAL(CASE_DATA_PHASE2_OK, current_case.received_data);
144+
current_case.received_data = CASE_DATA_INVALID;
145+
return;
146+
}
147+
148+
// Phase 1. -- run the test code.
149+
watchdog_config_t config = { TIMEOUT_LOWER_LIMIT_MS };
150+
uint32_t sleep_time_ms = (TIMEOUT_LOWER_LIMIT_MS * features.clock_typical_frequency / features.clock_max_frequency) - TIME_WINDOW_MS;
151+
TEST_ASSERT_EQUAL(WATCHDOG_STATUS_OK, hal_watchdog_init(&config));
152+
153+
// Kick watchdog before timeout.
154+
// Watchdog should not trigger before timeout * clock accuracy.
155+
// If device restarts while waiting for the kick, test fails.
156+
157+
wait_us(sleep_time_ms * 1000);
158+
hal_watchdog_kick();
159+
160+
if (send_reset_notification(&current_case, 2 * TIMEOUT_LOWER_LIMIT_MS) == false) {
161+
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
162+
return;
163+
}
164+
hal_watchdog_kick();
165+
166+
// Watchdog should fire before twice the timeout value.
167+
wait_us(2 * TIMEOUT_LOWER_LIMIT_MS * 1000);
168+
169+
// Watchdog reset should have occurred during that wait() above;
170+
171+
hal_watchdog_kick(); // Just to buy some time for testsuite failure handling.
172+
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
173+
}
174+
113175
utest::v1::status_t case_setup(const Case *const source, const size_t index_of_case)
114176
{
115177
current_case.index = index_of_case;
@@ -151,6 +213,7 @@ Case cases[] = {
151213
Case("Timing, 500 ms", case_setup, test_timing<500UL>),
152214
Case("Timing, 1000 ms", case_setup, test_timing<1000UL>),
153215
Case("Timing, 3000 ms", case_setup, test_timing<3000UL>),
216+
Case("timeout accuracy", case_setup, test_timeout_lower_limit)
154217
};
155218

156219
Specification specification((utest::v1::test_setup_handler_t) testsuite_setup, cases);

TESTS/mbed_hal/watchdog_timing/watchdog_timing_tests.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@
4040
template<uint32_t timeout_ms, uint32_t delta_ms>
4141
void test_timing();
4242

43+
/** Test Watchdog timeout
44+
*
45+
* Given a device with a Watchdog started,
46+
* when the Watchdog timout doesn't expire,
47+
* then the device restart is not performed.
48+
* When the Watchdog timout does expire,
49+
* then the device is restarted after the timeout and before twice the timeout value.
50+
*/
51+
void test_timeout_lower_limit();
52+
4353
#endif
4454

4555
#endif

hal/watchdog_api.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@
4747
* already initialized the hardware watchdog timer.
4848
* * Maximum supported timeout is `UINT32_MAX` milliseconds; minimum timeout
4949
* is 1 millisecond.
50-
* * The watchdog should trigger at or after the timeout value.
50+
* * The uncalibrated watchdog should trigger at or after the timeout value
51+
* multiplied by the frequency accuracy ratio of its oscillator (typical_frequency / max_frequency).
52+
* * The calibrated watchdog should trigger at or after the timeout value.
5153
* * The watchdog should trigger before twice the timeout value.
5254
*
5355
* # Undefined behavior
@@ -99,6 +101,14 @@ typedef struct {
99101
* You can stop the watchdog after it starts without a reset.
100102
*/
101103
bool disable_watchdog;
104+
/**
105+
* Typical frequency of not calibrated watchdog clock in Hz.
106+
*/
107+
uint32_t clock_typical_frequency;
108+
/**
109+
* Maximum frequency of not calibrated watchdog clock in Hz.
110+
*/
111+
uint32_t clock_max_frequency;
102112
} watchdog_features_t;
103113

104114

targets/TARGET_Cypress/TARGET_PSOC6/cy_watchdog_api.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ uint32_t hal_watchdog_get_reload_value(void)
6767
watchdog_features_t hal_watchdog_get_platform_features(void)
6868
{
6969
watchdog_features_t features = {
70-
/* .max_timeout = */ cyhal_wdt_get_max_timeout_ms(),
71-
/* .update_config = */ true,
72-
/* .disable_watchdog = */ true
70+
/* .max_timeout = */ cyhal_wdt_get_max_timeout_ms(),
71+
/* .update_config = */ true,
72+
/* .disable_watchdog = */ true,
73+
/* .clock_typical_frequency = */ 32000,
74+
/* .clock_max_frequency = */ 36100
7375
};
7476
return features;
7577
}

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/watchdog_api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
123123
features.max_timeout = MAX_TIMEOUT_MS;
124124
features.update_config = true;
125125
features.disable_watchdog = true;
126+
features.clock_typical_frequency = 1000;
127+
features.clock_max_frequency = 1111;
126128

127129
return features;
128130
}

targets/TARGET_NUVOTON/TARGET_M451/watchdog_api.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
125125
wdt_feat.update_config = 1;
126126
/* Support stopping watchdog timer */
127127
wdt_feat.disable_watchdog = 1;
128+
/* Accuracy of watchdog timer */
129+
wdt_feat.clock_typical_frequency = 10000;
130+
wdt_feat.clock_max_frequency = 15000;
128131

129132
return wdt_feat;
130133
}

targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
124124
wdt_feat.update_config = 1;
125125
/* Support stopping watchdog timer */
126126
wdt_feat.disable_watchdog = 1;
127+
/* Accuracy of watchdog timer */
128+
wdt_feat.clock_typical_frequency = 10000;
129+
wdt_feat.clock_max_frequency = 15000;
130+
127131

128132
return wdt_feat;
129133
}

targets/TARGET_NUVOTON/TARGET_NANO100/watchdog_api.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
130130
wdt_feat.update_config = 1;
131131
/* Support stopping watchdog timer */
132132
wdt_feat.disable_watchdog = 1;
133+
/* Accuracy of watchdog timer */
134+
wdt_feat.clock_typical_frequency = 10000;
135+
wdt_feat.clock_max_frequency = 15000;
133136

134137
return wdt_feat;
135138
}

targets/TARGET_NUVOTON/TARGET_NUC472/watchdog_api.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
124124
wdt_feat.update_config = 1;
125125
/* Support stopping watchdog timer */
126126
wdt_feat.disable_watchdog = 1;
127+
/* Accuracy of watchdog timer */
128+
wdt_feat.clock_typical_frequency = 10000;
129+
wdt_feat.clock_max_frequency = 14000;
127130

128131
return wdt_feat;
129132
}

targets/TARGET_NXP/TARGET_LPC176X/watchdog_api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
6363
features.max_timeout = ((float)INT32_MAX/clk)*1000;
6464
features.update_config = true;
6565
features.disable_watchdog = false;
66+
features.clock_typical_frequency = 4000000;
67+
features.clock_max_frequency = 4040000;
6668

6769
return features;
6870
}

targets/TARGET_ONSEMI/TARGET_NCS36510/watchdog_api.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
103103
const watchdog_features_t features = {
104104
.max_timeout = WDT_MAX_TIMEOUT_MS,
105105
.update_config = WDT_CAN_UPDATE,
106-
.disable_watchdog = WDT_CAN_STOP
106+
.disable_watchdog = WDT_CAN_STOP,
107+
.clock_typical_frequency = 36000,
108+
.clock_max_frequency = 47000
107109
};
108110

109111
return features;

targets/TARGET_STM/watchdog_api.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,24 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
123123
features.max_timeout = MAX_TIMEOUT_MS;
124124
features.update_config = true;
125125
features.disable_watchdog = false;
126+
127+
/* STM32 IWDG (Independent Watchdog) is clocked by its own dedicated low-speed clock (LSI) */
128+
features.clock_typical_frequency = LSI_VALUE;
129+
130+
/* See LSI oscillator characteristics in Data Sheet */
131+
#if defined(STM32F1)
132+
features.clock_max_frequency = 60000;
133+
#elif defined(STM32L0) || defined(STM32L1)
134+
features.clock_max_frequency = 56000;
135+
#elif defined(STM32F2) || defined(STM32F4) || defined(STM32F7)
136+
features.clock_max_frequency = 47000;
137+
#elif defined(STM32F0) || defined(STM32F3)
138+
features.clock_max_frequency = 50000;
139+
#elif defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
140+
features.clock_max_frequency = 33600;
141+
#else
142+
#error "unsupported target"
143+
#endif
126144

127145
return features;
128146
}

targets/TARGET_Silicon_Labs/TARGET_EFM32/watchdog_api.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,19 @@ watchdog_features_t hal_watchdog_get_platform_features(void)
9292
watchdog_features_t feat = {
9393
.max_timeout = 262145,
9494
.update_config = true,
95-
.disable_watchdog = true
95+
.disable_watchdog = true,
96+
#if defined(TARGET_EFM32GG) || defined(TARGET_EFM32HG) || defined(TARGET_EFM32LG) || defined(TARGET_EFM32WG) || defined(TARGET_EFM32ZG)
97+
.clock_typical_frequency = 1000,
98+
.clock_max_frequency = 1750
99+
#elif defined(TARGET_EFM32GG11)
100+
.clock_typical_frequency = 1000,
101+
.clock_max_frequency = 1120
102+
#elif defined(TARGET_EFM32PG) || defined(TARGET_EFM32PG12) || defined(TARGET_EFR32MG1) || defined(TARGET_EFR32MG12)
103+
.clock_typical_frequency = 1000,
104+
.clock_max_frequency = 1070
105+
#else
106+
#error "unsupported target"
107+
#endif
96108
};
97109
return feat;
98110
}

0 commit comments

Comments
 (0)