Skip to content

Commit 39436d7

Browse files
committed
drivers/timers/watchdog: add watchdog timer notifier chain
Add support for watchdog timer notifer chain so that users can customize the callback function when the watchdog timer times out which enabled by Auto-monitor Signed-off-by: yaojiaqi <[email protected]>
1 parent c55c251 commit 39436d7

File tree

6 files changed

+222
-0
lines changed

6 files changed

+222
-0
lines changed

drivers/timers/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ if(CONFIG_WATCHDOG)
2626
list(APPEND SRCS watchdog.c)
2727
endif()
2828

29+
if(CONFIG_WATCHDOG_TIMEOUT_NOTIFIER)
30+
list(APPEND SRCS watchdog_notifier.c)
31+
endif()
32+
2933
if(CONFIG_TIMER)
3034
list(APPEND SRCS timer.c)
3135
endif()

drivers/timers/Kconfig

+8
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,14 @@ menuconfig WATCHDOG_AUTOMONITOR
439439

440440
if WATCHDOG_AUTOMONITOR
441441

442+
config WATCHDOG_TIMEOUT_NOTIFIER
443+
bool "Enable watchdog timeout notifier"
444+
default n
445+
---help---
446+
The watchdog timeout notifier chain mechanism supports users registering
447+
custom callback functions, which will be called when the watchdog timer
448+
managed by Auto-monitor times out.
449+
442450
choice
443451
prompt "Auto-monitor keepalive by"
444452
default WATCHDOG_AUTOMONITOR_BY_WDOG

drivers/timers/Make.defs

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ ifeq ($(CONFIG_WATCHDOG),y)
2828
TMRVPATH = :timers
2929
endif
3030

31+
ifeq ($(CONFIG_WATCHDOG_TIMEOUT_NOTIFIER),y)
32+
CSRCS += watchdog_notifier.c
33+
TMRDEPPATH = --dep-path timers
34+
TMRVPATH = :timers
35+
endif
36+
3137
ifeq ($(CONFIG_TIMER),y)
3238
CSRCS += timer.c
3339
TMRDEPPATH = --dep-path timers

drivers/timers/watchdog.c

+29
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,19 @@
7171
# endif
7272
#endif
7373

74+
#if defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_ONESHOT)
75+
#define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_ONESHOT
76+
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_TIMER)
77+
#define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_TIMER
78+
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WDOG)
79+
#define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_WDOG
80+
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_WORKER)
81+
#define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_WORKER
82+
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_CAPTURE)
83+
#define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_CAPTURE
84+
#elif defined(CONFIG_WATCHDOG_AUTOMONITOR_BY_IDLE)
85+
#define WATCHDOG_NOTIFIER_ACTION WATCHDOG_KEEPALIVE_BY_IDLE
86+
#endif
7487
/****************************************************************************
7588
* Private Type Definitions
7689
****************************************************************************/
@@ -699,6 +712,22 @@ static int wdog_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
699712
* Public Functions
700713
****************************************************************************/
701714

715+
/****************************************************************************
716+
* Name: watchdog_automonitor_timeout
717+
*
718+
* Description:
719+
* This function can be called in the watchdog timeout interrupt handler.
720+
* If so, callbacks on the watchdog timer notify chain are called when the
721+
* watchdog timer times out.
722+
*
723+
****************************************************************************/
724+
#ifdef CONFIG_WATCHDOG_TIMEOUT_NOTIFIER
725+
void watchdog_automonitor_timeout(void)
726+
{
727+
watchdog_notifier_call_chain(WATCHDOG_NOTIFIER_ACTION, NULL);
728+
}
729+
#endif /* CONFIG_WATCHDOG_TIMEOUT_NOTIFIER */
730+
702731
/****************************************************************************
703732
* Name: watchdog_register
704733
*

drivers/timers/watchdog_notifier.c

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/****************************************************************************
2+
* drivers/timers/watchdog_notifier.c
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed to the Apache Software Foundation (ASF) under one or more
7+
* contributor license agreements. See the NOTICE file distributed with
8+
* this work for additional information regarding copyright ownership. The
9+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
10+
* "License"); you may not use this file except in compliance with the
11+
* License. You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18+
* License for the specific language governing permissions and limitations
19+
* under the License.
20+
*
21+
****************************************************************************/
22+
23+
/****************************************************************************
24+
* Included Files
25+
****************************************************************************/
26+
27+
#include <nuttx/arch.h>
28+
#include <nuttx/notifier.h>
29+
30+
#include <sys/types.h>
31+
32+
/****************************************************************************
33+
* Private Data
34+
****************************************************************************/
35+
36+
static ATOMIC_NOTIFIER_HEAD(g_watchdog_notifier_list);
37+
38+
/****************************************************************************
39+
* Public Functions
40+
****************************************************************************/
41+
42+
/****************************************************************************
43+
* Name: watchdog_notifier_chain_register
44+
*
45+
* Description:
46+
* Add notifier to the watchdog notifier chain
47+
*
48+
* Input Parameters:
49+
* nb - New entry in notifier chain
50+
*
51+
****************************************************************************/
52+
53+
void watchdog_notifier_chain_register(FAR struct notifier_block *nb)
54+
{
55+
atomic_notifier_chain_register(&g_watchdog_notifier_list, nb);
56+
}
57+
58+
/****************************************************************************
59+
* Name: watchdog_notifier_chain_unregister
60+
*
61+
* Description:
62+
* Remove notifier from the watchdog notifier chain
63+
*
64+
* Input Parameters:
65+
* nb - Entry to remove from notifier chain
66+
*
67+
****************************************************************************/
68+
69+
void watchdog_notifier_chain_unregister(FAR struct notifier_block *nb)
70+
{
71+
atomic_notifier_chain_unregister(&g_watchdog_notifier_list, nb);
72+
}
73+
74+
/****************************************************************************
75+
* Name: watchdog_notifier_call_chain
76+
*
77+
* Description:
78+
* Call functions in the watchdog notifier chain.
79+
*
80+
* Input Parameters:
81+
* action - Value passed unmodified to notifier function
82+
* data - Pointer passed unmodified to notifier function
83+
*
84+
****************************************************************************/
85+
86+
void watchdog_notifier_call_chain(unsigned long action, FAR void *data)
87+
{
88+
atomic_notifier_call_chain(&g_watchdog_notifier_list, action, data);
89+
}

include/nuttx/timers/watchdog.h

+86
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <nuttx/compiler.h>
3232
#include <nuttx/irq.h>
3333
#include <nuttx/fs/ioctl.h>
34+
#include <nuttx/notifier.h>
35+
#include <nuttx/sched.h>
3436

3537
#ifdef CONFIG_WATCHDOG
3638

@@ -88,6 +90,35 @@
8890
#define WDFLAGS_CAPTURE (1 << 2) /* 1=Call the user function when the
8991
* watchdog timer expires */
9092

93+
/* Keepalive Actions ********************************************************/
94+
95+
/* According to the keepalive action specified by the Auto-monitor, callback
96+
* functions registered on the watchdog notifier chain may take corresponding
97+
* actions.
98+
*
99+
* These are detected and handled by the "upper half" watchdog timer driver.
100+
*
101+
* WATCHDOG_KEEPALIVE_BY_ONESHOT - The watchdog timer is keepalive by
102+
* oneshot timer.
103+
* WATCHDOG_KEEPALIVE_BY_TIMER - The watchdog timer is keepalive by
104+
* timer.
105+
* WATCHDOG_KEEPALIVE_BY_WDOG - The watchdog timer is keepalive by
106+
* wdog.
107+
* WATCHDOG_KEEPALIVE_BY_WORKER - The watchdog timer is keepalive by
108+
* worker queue.
109+
* WATCHDOG_KEEPALIVE_BY_CAPTURE - The watchdog timer is keepalive by
110+
* capture.
111+
* WATCHDOG_KEEPALIVE_BY_IDLE - The watchdog timer is keepalive by
112+
* idle task.
113+
*/
114+
115+
#define WATCHDOG_KEEPALIVE_BY_ONESHOT 0
116+
#define WATCHDOG_KEEPALIVE_BY_TIMER 1
117+
#define WATCHDOG_KEEPALIVE_BY_WDOG 2
118+
#define WATCHDOG_KEEPALIVE_BY_WORKER 3
119+
#define WATCHDOG_KEEPALIVE_BY_CAPTURE 4
120+
#define WATCHDOG_KEEPALIVE_BY_IDLE 5
121+
91122
/****************************************************************************
92123
* Public Types
93124
****************************************************************************/
@@ -197,6 +228,61 @@ extern "C"
197228
#define EXTERN extern
198229
#endif
199230

231+
#ifdef CONFIG_WATCHDOG_TIMEOUT_NOTIFIER
232+
/****************************************************************************
233+
* Name: watchdog_notifier_chain_register
234+
*
235+
* Description:
236+
* Add notifier to the watchdog notifier chain
237+
*
238+
* Input Parameters:
239+
* nb - New entry in notifier chain
240+
*
241+
****************************************************************************/
242+
243+
void watchdog_notifier_chain_register(FAR struct notifier_block *nb);
244+
245+
/****************************************************************************
246+
* Name: watchdog_notifier_chain_unregister
247+
*
248+
* Description:
249+
* Remove notifier from the watchdog notifier chain
250+
*
251+
* Input Parameters:
252+
* nb - Entry to remove from notifier chain
253+
*
254+
****************************************************************************/
255+
256+
void watchdog_notifier_chain_unregister(FAR struct notifier_block *nb);
257+
258+
/****************************************************************************
259+
* Name: watchdog_notifier_call_chain
260+
*
261+
* Description:
262+
* Call functions in the watchdog notifier chain.
263+
*
264+
* Input Parameters:
265+
* action - Value passed unmodified to notifier function
266+
* data - Pointer passed unmodified to notifier function
267+
*
268+
****************************************************************************/
269+
270+
void watchdog_notifier_call_chain(unsigned long action, FAR void *data);
271+
272+
/****************************************************************************
273+
* Name: watchdog_automonitor_timeout
274+
*
275+
* Description:
276+
* This function can be called in the watchdog timeout interrupt handler.
277+
* If so, callbacks on the watchdog timer notify chain are called when the
278+
* watchdog timer times out.
279+
*
280+
****************************************************************************/
281+
282+
void watchdog_automonitor_timeout(void);
283+
284+
#endif /* CONFIG_WATCHDOG_TIMEOUT_NOTIFIER */
285+
200286
/****************************************************************************
201287
* Name: watchdog_register
202288
*

0 commit comments

Comments
 (0)