Skip to content

Commit 81df84a

Browse files
nordic-seglfabiobaltieri
authored andcommitted
tests: drivers: watchdog: Add test for initialization of .bss and .data
In some configurations, code is copied from non-volatile memory to RAM before a core (using that code) is booted. When that core is reset by expired watchdog, variables shall be restored to "initial" values. This is problematic because the core is aware of copy in RAM. It may not know address in non-volatile memory, where "original" code is stored. Add tests which verifiest that .bss and .data sections are correct when core boots from reset caused by expired watchdog. Signed-off-by: Sebastian Głąb <sebastian.glab@nordicsemi.no>
1 parent 9c4d626 commit 81df84a

12 files changed

+253
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
7+
project(wdt_variables)
8+
9+
target_sources(app PRIVATE src/main.c)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
&wdt010 {
8+
status = "okay";
9+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
watchdog0 = &wdt132;
10+
};
11+
};
12+
13+
&wdt132 {
14+
status = "okay";
15+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
watchdog0 = &wdt131;
10+
};
11+
};
12+
13+
&wdt131 {
14+
status = "okay";
15+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
&wdt31 {
8+
status = "okay";
9+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
&wdt31 {
8+
status = "okay";
9+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
&wdt31 {
8+
status = "okay";
9+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CONFIG_LOG=y
2+
CONFIG_LOG_MODE_IMMEDIATE=y
3+
CONFIG_WATCHDOG=y
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/logging/log.h>
8+
LOG_MODULE_REGISTER(wdt_vars, LOG_LEVEL_INF);
9+
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/cache.h>
12+
#include <zephyr/drivers/watchdog.h>
13+
14+
#define WDT_WINDOW_MAX (500)
15+
16+
/* Watchdog related variables */
17+
static const struct device *const my_wdt_device = DEVICE_DT_GET(DT_ALIAS(watchdog0));
18+
static struct wdt_timeout_cfg m_cfg_wdt0;
19+
20+
/* No init section will contain WDT_HAS_FIRED if watchdog has fired */
21+
#define WDT_HAS_FIRED (12345678U)
22+
#define TEST_VALUE (2U)
23+
24+
#define NOINIT_SECTION ".noinit.test_wdt"
25+
static volatile uint32_t wdt_status __attribute__((section(NOINIT_SECTION)));
26+
27+
/* Global variables to verify */
28+
static int global_tmp_0;
29+
static int global_tmp_1 = TEST_VALUE;
30+
31+
32+
static void wdt_int_cb(const struct device *wdt_dev, int channel_id)
33+
{
34+
ARG_UNUSED(wdt_dev);
35+
ARG_UNUSED(channel_id);
36+
wdt_status = WDT_HAS_FIRED;
37+
38+
/* Flush cache as reboot may invalidate all lines. */
39+
sys_cache_data_flush_range((void *) &wdt_status, sizeof(wdt_status));
40+
}
41+
42+
int main(void)
43+
{
44+
int ret;
45+
static int tmp_0;
46+
static int tmp_1 = TEST_VALUE;
47+
48+
LOG_INF("wdt_variables test on %s", CONFIG_BOARD_TARGET);
49+
50+
global_tmp_0++;
51+
global_tmp_1++;
52+
tmp_0++;
53+
tmp_1++;
54+
55+
LOG_DBG("global_tmp_0 = %d", global_tmp_0);
56+
LOG_DBG("global_tmp_1 = %d", global_tmp_1);
57+
LOG_DBG("tmp_0 = %d", tmp_0);
58+
LOG_DBG("tmp_1 = %d", tmp_1);
59+
60+
/* When watchdog fires, variable wdt_status is set to the value of WDT_HAS_FIRED
61+
* in WDT callback wdt_int_cb(). Then, target is reset.
62+
* Check value of wdt_status to prevent reset loop.
63+
*/
64+
if (wdt_status != WDT_HAS_FIRED) {
65+
66+
LOG_INF("Reset wasn't due to watchdog.");
67+
68+
if (!device_is_ready(my_wdt_device)) {
69+
LOG_ERR("WDT device %s is not ready", my_wdt_device->name);
70+
return 1;
71+
}
72+
73+
/* Configure Watchdog */
74+
m_cfg_wdt0.callback = wdt_int_cb;
75+
m_cfg_wdt0.flags = WDT_FLAG_RESET_SOC;
76+
m_cfg_wdt0.window.min = 0U;
77+
m_cfg_wdt0.window.max = WDT_WINDOW_MAX;
78+
ret = wdt_install_timeout(my_wdt_device, &m_cfg_wdt0);
79+
if (ret < 0) {
80+
LOG_ERR("wdt_install_timeout() returned %d", ret);
81+
return 1;
82+
}
83+
84+
/* Start Watchdog */
85+
ret = wdt_setup(my_wdt_device, WDT_OPT_PAUSE_HALTED_BY_DBG);
86+
if (ret < 0) {
87+
LOG_ERR("wdt_setup() returned %d", ret);
88+
return 1;
89+
}
90+
91+
LOG_INF("Watchdog shall fire in ~%u miliseconds", WDT_WINDOW_MAX);
92+
k_sleep(K_FOREVER);
93+
} else {
94+
bool test_passing = true;
95+
96+
LOG_INF("Watchod has fired");
97+
98+
if (global_tmp_0 != 1) {
99+
LOG_ERR("global_tmp_0 is %d instead of 1", global_tmp_0);
100+
test_passing = false;
101+
}
102+
103+
if (global_tmp_1 != (TEST_VALUE + 1)) {
104+
LOG_ERR("global_tmp_1 is %d instead of %d", global_tmp_1, TEST_VALUE + 1);
105+
test_passing = false;
106+
}
107+
108+
if (tmp_0 != 1) {
109+
LOG_ERR("tmp_0 is %d instead of 1", tmp_0);
110+
test_passing = false;
111+
}
112+
113+
if (tmp_1 != (TEST_VALUE + 1)) {
114+
LOG_ERR("tmp_1 is %d instead of %d", tmp_1, TEST_VALUE + 1);
115+
test_passing = false;
116+
}
117+
118+
/* Cleanup */
119+
wdt_status = 0;
120+
sys_cache_data_flush_range((void *) &wdt_status, sizeof(wdt_status));
121+
122+
if (test_passing) {
123+
LOG_INF("Test completed successfully");
124+
} else {
125+
LOG_INF("Test failed");
126+
}
127+
}
128+
129+
return 0;
130+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
&wdt131 {
8+
status = "reserved";
9+
interrupt-parent = <&cpuppr_clic>;
10+
};
11+
12+
&wdt132 {
13+
status = "reserved";
14+
interrupt-parent = <&cpuflpr_clic>;
15+
};

0 commit comments

Comments
 (0)