From 51399a76d9606b0aa725d7b945afa1680a5fdaf2 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Thu, 21 Nov 2024 16:14:35 +0800 Subject: [PATCH] sched/wdog: support for periodic wdog. This commit added support for periodic wdog. Signed-off-by: ouyangxiangzhen --- include/nuttx/wdog.h | 56 +++++++++++++++++++++++++++++++++- sched/wdog/wd_start.c | 71 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/include/nuttx/wdog.h b/include/nuttx/wdog.h index b146e1af585..393aa73cc9c 100644 --- a/include/nuttx/wdog.h +++ b/include/nuttx/wdog.h @@ -31,7 +31,6 @@ #include #include -#include #include /**************************************************************************** @@ -90,6 +89,13 @@ struct wdog_s clock_t expired; /* Timer associated with the absoulute time */ }; +struct wdog_period_s +{ + struct wdog_s wdog; /* Watchdog */ + clock_t period; /* Period time in ticks */ + wdentry_t func; /* Wrapped function to execute when delay expires */ +}; + /**************************************************************************** * Pubic Function Prototypes ****************************************************************************/ @@ -279,6 +285,34 @@ static inline int wd_start_realtime(FAR struct wdog_s *wdog, #endif } +/**************************************************************************** + * Name: wd_start_period + * + * Description: + * This function periodically adds a watchdog timer to the active timer. + * + * Input Parameters: + * wdog - Pointer of the periodic watchdog. + * delay - Delayed time in system ticks. + * period - Period in system ticks. + * wdentry - Function to call on timeout. + * arg - Parameter to pass to wdentry. + * + * NOTE: The parameter must be of type wdparm_t. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is return to + * indicate the nature of any failure. + * + * Assumptions: + * The watchdog routine runs in the context of the timer interrupt handler + * and is subject to all ISR restrictions. + * + ****************************************************************************/ + +int wd_start_period(FAR struct wdog_period_s *wdog, sclock_t delay, + clock_t period, wdentry_t wdentry, wdparm_t arg); + /**************************************************************************** * Name: wd_cancel * @@ -297,6 +331,26 @@ static inline int wd_start_realtime(FAR struct wdog_s *wdog, int wd_cancel(FAR struct wdog_s *wdog); +/**************************************************************************** + * Name: wd_cancel_period + * + * Description: + * This function cancels a currently running periodic watchdog timer. + * + * Input Parameters: + * wdog_period - Pointer of the periodic watchdog. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned to + * indicate the nature of any failure. + * + ****************************************************************************/ + +static inline int wd_cancel_period(FAR struct wdog_period_s *wdog_period) +{ + return wd_cancel(&wdog_period->wdog); +} + /**************************************************************************** * Name: wd_gettime * diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c index ca5b7bea336..e0e5a640bec 100644 --- a/sched/wdog/wd_start.c +++ b/sched/wdog/wd_start.c @@ -94,6 +94,35 @@ static unsigned int g_wdtimernested; * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: wdentry_period + * + * Description: + * Periodic watchdog timer callback function. + * + * Input Parameters: + * arg - The argument of the wdog callback. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wdentry_period(wdparm_t arg) +{ + FAR struct wdog_period_s *wdperiod = (FAR struct wdog_period_s *)arg; + + wdperiod->func(wdperiod->wdog.arg); + + /* Since we set `ticks++` at `wd_start_abstick`, + * we need to use `expired - 1` here to avoid time drift. + */ + + wd_start_abstick(&wdperiod->wdog, + wdperiod->wdog.expired + wdperiod->period - 1, + wdentry_period, wdperiod->wdog.arg); +} + /**************************************************************************** * Name: wd_expiration * @@ -151,6 +180,9 @@ static inline_function void wd_expiration(clock_t ticks) arg = wdog->arg; wdog->func = NULL; + arg = func != wdentry_period ? wdog->arg : + (wdparm_t)list_container_of(wdog, struct wdog_period_s, wdog); + /* Execute the watchdog function */ up_setpicbase(wdog->picbase); @@ -396,6 +428,45 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay, wdentry, arg); } +/**************************************************************************** + * Name: wd_start_period + * + * Description: + * This function periodically adds a watchdog timer to the active timer. + * + * Input Parameters: + * wdog - Pointer of the periodic watchdog. + * delay - Delayed time in system ticks. + * period - Period in system ticks. + * wdentry - Function to call on timeout. + * arg - Parameter to pass to wdentry. + * + * NOTE: The parameter must be of type wdparm_t. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is return to + * indicate the nature of any failure. + * + * Assumptions: + * The watchdog routine runs in the context of the timer interrupt handler + * and is subject to all ISR restrictions. + * + ****************************************************************************/ + +int wd_start_period(FAR struct wdog_period_s *wdog, sclock_t delay, + clock_t period, wdentry_t wdentry, wdparm_t arg) +{ + if (!wdog || !period || !wdentry) + { + return -EINVAL; + } + + wdog->func = wdentry; + wdog->period = period; + + return wd_start(&wdog->wdog, delay, wdentry_period, arg); +} + /**************************************************************************** * Name: wd_timer *