-
Notifications
You must be signed in to change notification settings - Fork 6.5k
/
main.c
145 lines (124 loc) · 3.74 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* Copyright (c) 2015 Intel Corporation
* Copyright (c) 2018 Nordic Semiconductor
* Copyright (c) 2019 Centaur Analytics, Inc
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <device.h>
#include <drivers/watchdog.h>
#include <sys/printk.h>
#include <stdbool.h>
#define WDT_FEED_TRIES 5
/*
* 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)
#define WDT_MAX_WINDOW 100U
#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)
/* Nordic supports a callback, but it has 61.2 us to complete before
* the reset occurs, which is too short for this sample to do anything
* useful. Explicitly disallow use of the callback.
*/
#define WDT_ALLOW_CALLBACK 0
#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)
#elif DT_HAS_COMPAT_STATUS_OKAY(ti_cc32xx_watchdog)
#define WDT_NODE DT_INST(0, ti_cc32xx_watchdog)
#endif
#ifndef WDT_ALLOW_CALLBACK
#define WDT_ALLOW_CALLBACK 1
#endif
#ifndef WDT_MAX_WINDOW
#define WDT_MAX_WINDOW 1000U
#endif
/*
* If the devicetree has a watchdog node, get its label property.
*/
#ifdef WDT_NODE
#define WDT_DEV_NAME DT_LABEL(WDT_NODE)
#else
#define WDT_DEV_NAME ""
#error "Unsupported SoC and no watchdog0 alias in zephyr.dts"
#endif
#if WDT_ALLOW_CALLBACK
static void wdt_callback(const struct device *wdt_dev, int channel_id)
{
static bool handled_event;
if (handled_event) {
return;
}
wdt_feed(wdt_dev, channel_id);
printk("Handled things..ready to reset\n");
handled_event = true;
}
#endif /* WDT_ALLOW_CALLBACK */
void main(void)
{
int err;
int wdt_channel_id;
const struct device *wdt;
printk("Watchdog sample application\n");
wdt = device_get_binding(WDT_DEV_NAME);
if (!wdt) {
printk("Cannot get WDT device\n");
return;
}
struct wdt_timeout_cfg wdt_config = {
/* Reset SoC when watchdog timer expires. */
.flags = WDT_FLAG_RESET_SOC,
/* Expire watchdog after max window */
.window.min = 0U,
.window.max = WDT_MAX_WINDOW,
};
#if WDT_ALLOW_CALLBACK
/* Set up watchdog callback. */
wdt_config.callback = wdt_callback;
printk("Attempting to test pre-reset callback\n");
#else /* WDT_ALLOW_CALLBACK */
printk("Callback in RESET_SOC disabled for this platform\n");
#endif /* WDT_ALLOW_CALLBACK */
wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
if (wdt_channel_id == -ENOTSUP) {
/* IWDG driver for STM32 doesn't support callback */
printk("Callback support rejected, continuing anyway\n");
wdt_config.callback = NULL;
wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
}
if (wdt_channel_id < 0) {
printk("Watchdog install error\n");
return;
}
err = wdt_setup(wdt, 0);
if (err < 0) {
printk("Watchdog setup error\n");
return;
}
/* Feeding watchdog. */
printk("Feeding watchdog %d times\n", WDT_FEED_TRIES);
for (int i = 0; i < WDT_FEED_TRIES; ++i) {
printk("Feeding watchdog...\n");
wdt_feed(wdt, wdt_channel_id);
k_sleep(K_MSEC(50));
}
/* Waiting for the SoC reset. */
printk("Waiting for reset...\n");
while (1) {
k_yield();
}
}