Skip to content

Commit

Permalink
[nrf fromlist] tests: drivers: watchdog: Add test for initialization …
Browse files Browse the repository at this point in the history
…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.

Upstream PR #: 86217

Signed-off-by: Sebastian Głąb <[email protected]>
  • Loading branch information
nordic-segl committed Feb 26, 2025
1 parent d445231 commit d56eefc
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 0 deletions.
9 changes: 9 additions & 0 deletions tests/drivers/watchdog/wdt_variables/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

project(wdt_variables)

target_sources(app PRIVATE src/main.c)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

&wdt010 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
aliases {
watchdog0 = &wdt132;
};
};

&wdt132 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
aliases {
watchdog0 = &wdt131;
};
};

&wdt131 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

&wdt31 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

&wdt31 {
status = "okay";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

&wdt31 {
status = "okay";
};
3 changes: 3 additions & 0 deletions tests/drivers/watchdog/wdt_variables/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_LOG=y
CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_WATCHDOG=y
130 changes: 130 additions & 0 deletions tests/drivers/watchdog/wdt_variables/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(wdt_vars, LOG_LEVEL_INF);

#include <zephyr/kernel.h>
#include <zephyr/cache.h>
#include <zephyr/drivers/watchdog.h>

#define WDT_WINDOW_MAX (500)

/* Watchdog related variables */
static const struct device *const my_wdt_device = DEVICE_DT_GET(DT_ALIAS(watchdog0));
static struct wdt_timeout_cfg m_cfg_wdt0;

/* No init section will contain WDT_HAS_FIRED if watchdog has fired */
#define WDT_HAS_FIRED (12345678U)
#define TEST_VALUE (2U)

#define NOINIT_SECTION ".noinit.test_wdt"
static volatile uint32_t wdt_status __attribute__((section(NOINIT_SECTION)));

/* Global variables to verify */
static int global_tmp_0;
static int global_tmp_1 = TEST_VALUE;


static void wdt_int_cb(const struct device *wdt_dev, int channel_id)
{
ARG_UNUSED(wdt_dev);
ARG_UNUSED(channel_id);
wdt_status = WDT_HAS_FIRED;

/* Flush cache as reboot may invalidate all lines. */
sys_cache_data_flush_range((void *) &wdt_status, sizeof(wdt_status));
}

int main(void)
{
int ret;
static int tmp_0;
static int tmp_1 = TEST_VALUE;

LOG_INF("wdt_variables test on %s", CONFIG_BOARD_TARGET);

global_tmp_0++;
global_tmp_1++;
tmp_0++;
tmp_1++;

LOG_DBG("global_tmp_0 = %d", global_tmp_0);
LOG_DBG("global_tmp_1 = %d", global_tmp_1);
LOG_DBG("tmp_0 = %d", tmp_0);
LOG_DBG("tmp_1 = %d", tmp_1);

/* When watchdog fires, variable wdt_status is set to the value of WDT_HAS_FIRED
* in WDT callback wdt_int_cb(). Then, target is reset.
* Check value of wdt_status to prevent reset loop.
*/
if (wdt_status != WDT_HAS_FIRED) {

LOG_INF("Reset wasn't due to watchdog.");

if (!device_is_ready(my_wdt_device)) {
LOG_ERR("WDT device %s is not ready", my_wdt_device->name);
return 1;
}

/* Configure Watchdog */
m_cfg_wdt0.callback = wdt_int_cb;
m_cfg_wdt0.flags = WDT_FLAG_RESET_SOC;
m_cfg_wdt0.window.min = 0U;
m_cfg_wdt0.window.max = WDT_WINDOW_MAX;
ret = wdt_install_timeout(my_wdt_device, &m_cfg_wdt0);
if (ret < 0) {
LOG_ERR("wdt_install_timeout() returned %d", ret);
return 1;
}

/* Start Watchdog */
ret = wdt_setup(my_wdt_device, WDT_OPT_PAUSE_HALTED_BY_DBG);
if (ret < 0) {
LOG_ERR("wdt_setup() returned %d", ret);
return 1;
}

LOG_INF("Watchdog shall fire in ~%u miliseconds", WDT_WINDOW_MAX);
k_sleep(K_FOREVER);
} else {
bool test_passing = true;

LOG_INF("Watchod has fired");

if (global_tmp_0 != 1) {
LOG_ERR("global_tmp_0 is %d instead of 1", global_tmp_0);
test_passing = false;
}

if (global_tmp_1 != (TEST_VALUE + 1)) {
LOG_ERR("global_tmp_1 is %d instead of %d", global_tmp_1, TEST_VALUE + 1);
test_passing = false;
}

if (tmp_0 != 1) {
LOG_ERR("tmp_0 is %d instead of 1", tmp_0);
test_passing = false;
}

if (tmp_1 != (TEST_VALUE + 1)) {
LOG_ERR("tmp_1 is %d instead of %d", tmp_1, TEST_VALUE + 1);
test_passing = false;
}

/* Cleanup */
wdt_status = 0;
sys_cache_data_flush_range((void *) &wdt_status, sizeof(wdt_status));

if (test_passing) {
LOG_INF("Test completed successfully");
} else {
LOG_INF("Test failed");
}
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

&wdt131 {
status = "reserved";
interrupt-parent = <&cpuppr_clic>;
};

&wdt132 {
status = "reserved";
interrupt-parent = <&cpuflpr_clic>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# nothing here
29 changes: 29 additions & 0 deletions tests/drivers/watchdog/wdt_variables/testcase.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
common:
timeout: 10
tags:
- drivers
- watchdog
harness: console
harness_config:
type: one_line
regex:
- "Test completed successfully"

tests:
drivers.watchdog.wdt_variables.default:
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
- nrf54h20dk/nrf54h20/cpuppr
- nrf54l09pdk/nrf54l09/cpuapp
- nrf54l15dk/nrf54l15/cpuapp
- nrf54l20pdk/nrf54l20/cpuapp
integration_platforms:
- nrf54l15dk/nrf54l15/cpuapp

drivers.watchdog.wdt_variables.54h_flpr:
platform_allow:
- nrf54h20dk/nrf54h20/cpuflpr
extra_args:
- vpr_launcher_SNIPPET=nordic-log-stm
- vpr_launcher_CONFIG_BOOT_BANNER=n
- SNIPPET=nordic-log-stm

0 comments on commit d56eefc

Please sign in to comment.