From 2857c2e9845a328e2bee2be9005071e46db8b8bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20J=C3=A4ger?= Date: Wed, 25 Nov 2020 17:39:28 +0100 Subject: [PATCH] samples: subsys: task_wdt: add sample application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sample demonstrates how to use the task watchdog in different threads. Signed-off-by: Martin Jäger --- samples/subsys/task_wdt/CMakeLists.txt | 7 ++ samples/subsys/task_wdt/README.rst | 48 +++++++++++ samples/subsys/task_wdt/prj.conf | 10 +++ samples/subsys/task_wdt/sample.yaml | 20 +++++ samples/subsys/task_wdt/src/main.c | 114 +++++++++++++++++++++++++ 5 files changed, 199 insertions(+) create mode 100644 samples/subsys/task_wdt/CMakeLists.txt create mode 100644 samples/subsys/task_wdt/README.rst create mode 100644 samples/subsys/task_wdt/prj.conf create mode 100644 samples/subsys/task_wdt/sample.yaml create mode 100644 samples/subsys/task_wdt/src/main.c diff --git a/samples/subsys/task_wdt/CMakeLists.txt b/samples/subsys/task_wdt/CMakeLists.txt new file mode 100644 index 00000000000..72466893f9a --- /dev/null +++ b/samples/subsys/task_wdt/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13.1) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(task_wdt) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/subsys/task_wdt/README.rst b/samples/subsys/task_wdt/README.rst new file mode 100644 index 00000000000..d5e1bfe41ed --- /dev/null +++ b/samples/subsys/task_wdt/README.rst @@ -0,0 +1,48 @@ +.. _task_wdt_sample: + +Task Watchdog Sample +#################### + +Overview +******** + +This sample allows to test the task watchdog subsystem. + +Building and Running +******************** + +It should be possible to build and run the task watchdog sample on almost any +board. If a hardware watchdog is defined in the devicetree, it is used as a +fallback. Otherwise the task watchdog will run independently. + +Building and Running for ST Nucleo L073RZ +========================================= +The sample can be built and executed for the +:ref:`nucleo_l073rz_board` as follows: + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/task_wdt + :board: nucleo_l073rz + :goals: build flash + :compact: + +For other boards just replace the board name. + +Sample output +============= + +The following output is printed and continuously repeated (after each +reset): + +.. code-block:: console + +Task watchdog sample application. +Main thread still alive... +Control thread started. +Main thread still alive... +Main thread still alive... +Main thread still alive... +Control thread getting stuck... +Main thread still alive... +Task watchdog channel 1 callback, thread: control +Resetting device... diff --git a/samples/subsys/task_wdt/prj.conf b/samples/subsys/task_wdt/prj.conf new file mode 100644 index 00000000000..6ceb475efd5 --- /dev/null +++ b/samples/subsys/task_wdt/prj.conf @@ -0,0 +1,10 @@ +CONFIG_LOG=y + +CONFIG_WATCHDOG=y +CONFIG_WDT_LOG_LEVEL_DBG=y +CONFIG_WDT_DISABLE_AT_BOOT=y + +CONFIG_TASK_WDT=y +CONFIG_TASK_WDT_MIN_TIMEOUT=50 + +CONFIG_THREAD_NAME=y diff --git a/samples/subsys/task_wdt/sample.yaml b/samples/subsys/task_wdt/sample.yaml new file mode 100644 index 00000000000..cf802db11c7 --- /dev/null +++ b/samples/subsys/task_wdt/sample.yaml @@ -0,0 +1,20 @@ +sample: + name: Task Watchdog Subsytem Sample +tests: + sample.subsys.task_wdt: + tags: subsys + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "Task watchdog sample application." + - "Control thread started." + - "Main thread still alive..." + - "Control thread getting stuck..." + - "Task watchdog channel 1 callback, thread: control" + - "Resetting device...(.*)" + - "Task watchdog sample application." + depends_on: watchdog + integration_platforms: + - nucleo_g474re diff --git a/samples/subsys/task_wdt/src/main.c b/samples/subsys/task_wdt/src/main.c new file mode 100644 index 00000000000..4b2dea92968 --- /dev/null +++ b/samples/subsys/task_wdt/src/main.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020 Libre Solar Technologies GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * To use this sample, either the devicetree's /aliases must have a + * 'watchdog0' property, or one of the following watchdog compatibles + * must have an enabled node. + */ +#if DT_NODE_HAS_STATUS(DT_ALIAS(watchdog0), okay) +#define WDT_NODE DT_ALIAS(watchdog0) +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_window_watchdog) +#define WDT_NODE DT_INST(0, st_stm32_window_watchdog) +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_watchdog) +#define WDT_NODE DT_INST(0, st_stm32_watchdog) +#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_watchdog) +#define WDT_NODE DT_INST(0, nordic_nrf_watchdog) +#elif DT_HAS_COMPAT_STATUS_OKAY(espressif_esp32_watchdog) +#define WDT_NODE DT_INST(0, espressif_esp32_watchdog) +#elif DT_HAS_COMPAT_STATUS_OKAY(silabs_gecko_wdog) +#define WDT_NODE DT_INST(0, silabs_gecko_wdog) +#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_kinetis_wdog32) +#define WDT_NODE DT_INST(0, nxp_kinetis_wdog32) +#elif DT_HAS_COMPAT_STATUS_OKAY(microchip_xec_watchdog) +#define WDT_NODE DT_INST(0, microchip_xec_watchdog) +#endif + +/* + * If the devicetree has a watchdog node, get its label property. Otherwise + * the task watchdog will be used without a hardware watchdog fallback. + */ +#ifdef WDT_NODE +#define WDT_DEV_NAME DT_LABEL(WDT_NODE) +#endif + +static void task_wdt_callback(int channel_id, void *user_data) +{ + printk("Task watchdog channel %d callback, thread: %s\n", + channel_id, k_thread_name_get((k_tid_t)user_data)); + + /* + * If the issue could be resolved, call task_wdt_feed(channel_id) here + * to continue operation. + * + * Otherwise we can perform some cleanup and reset the device. + */ + + printk("Resetting device...\n"); + + sys_reboot(SYS_REBOOT_COLD); +} + +void main(void) +{ +#ifdef WDT_DEV_NAME + const struct device *hw_wdt_dev = device_get_binding(WDT_DEV_NAME); +#else + const struct device *hw_wdt_dev = NULL; +#endif + + printk("Task watchdog sample application.\n"); + + task_wdt_init(hw_wdt_dev); + + /* passing NULL instead of callback to trigger system reset */ + int task_wdt_id = task_wdt_add(1100U, NULL, NULL); + + while (true) { + printk("Main thread still alive...\n"); + task_wdt_feed(task_wdt_id); + k_sleep(K_MSEC(1000)); + } +} + +/* + * This high-priority thread needs a tight timing + */ +void control_thread(void) +{ + int task_wdt_id; + int count = 0; + + printk("Control thread started.\n"); + + /* + * Add a new task watchdog channel with custom callback function and + * the current thread ID as user data. + */ + task_wdt_id = task_wdt_add(100U, task_wdt_callback, + (void *)k_current_get()); + + while (true) { + if (count == 50) { + printk("Control thread getting stuck...\n"); + k_sleep(K_FOREVER); + } + + task_wdt_feed(task_wdt_id); + k_sleep(K_MSEC(50)); + count++; + } +} + +K_THREAD_DEFINE(control, 1024, control_thread, NULL, NULL, NULL, -1, 0, 1000);