zephyr/samples/subsys/task_wdt/src/main.c
Gerard Marull-Paretas 79e6b0e0f6 includes: prefer <zephyr/kernel.h> over <zephyr/zephyr.h>
As of today <zephyr/zephyr.h> is 100% equivalent to <zephyr/kernel.h>.
This patch proposes to then include <zephyr/kernel.h> instead of
<zephyr/zephyr.h> since it is more clear that you are including the
Kernel APIs and (probably) nothing else. <zephyr/zephyr.h> sounds like a
catch-all header that may be confusing. Most applications need to
include a bunch of other things to compile, e.g. driver headers or
subsystem headers like BT, logging, etc.

The idea of a catch-all header in Zephyr is probably not feasible
anyway. Reason is that Zephyr is not a library, like it could be for
example `libpython`. Zephyr provides many utilities nowadays: a kernel,
drivers, subsystems, etc and things will likely grow. A catch-all header
would be massive, difficult to keep up-to-date. It is also likely that
an application will only build a small subset. Note that subsystem-level
headers may use a catch-all approach to make things easier, though.

NOTE: This patch is **NOT** removing the header, just removing its usage
in-tree. I'd advocate for its deprecation (add a #warning on it), but I
understand many people will have concerns.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-09-05 16:31:47 +02:00

119 lines
3.2 KiB
C

/*
* Copyright (c) 2020 Libre Solar Technologies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/sys/reboot.h>
#include <zephyr/task_wdt/task_wdt.h>
#include <zephyr/sys/printk.h>
#include <stdbool.h>
/*
* 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 the devicetree has a watchdog node, we get the watchdog device
* from there. Otherwise, the task watchdog will be used without a
* hardware watchdog fallback.
*/
#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_COMPAT_GET_ANY_STATUS_OKAY(st_stm32_window_watchdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(st_stm32_watchdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_wdt)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nordic_nrf_wdt)
#elif DT_HAS_COMPAT_STATUS_OKAY(espressif_esp32_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(espressif_esp32_watchdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(silabs_gecko_wdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(silabs_gecko_wdog)
#elif DT_HAS_COMPAT_STATUS_OKAY(nxp_kinetis_wdog32)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(nxp_kinetis_wdog32)
#elif DT_HAS_COMPAT_STATUS_OKAY(microchip_xec_watchdog)
#define WDT_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(microchip_xec_watchdog)
#else
#define WDT_NODE DT_INVALID_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)
{
int ret;
const struct device *const hw_wdt_dev = DEVICE_DT_GET_OR_NULL(WDT_NODE);
printk("Task watchdog sample application.\n");
if (!device_is_ready(hw_wdt_dev)) {
printk("Hardware watchdog not ready; ignoring it.\n");
}
ret = task_wdt_init(hw_wdt_dev);
if (ret != 0) {
printk("task wdt init failure: %d\n", ret);
return;
}
/* 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);