From 578ecef9758c8bf8b26463922495ddc4e2085e1d Mon Sep 17 00:00:00 2001 From: ligd Date: Wed, 7 Aug 2024 21:04:52 +0800 Subject: [PATCH] wdog: add new API wd_start_realtime() support Signed-off-by: ligd --- include/nuttx/clock.h | 22 +++++++ include/nuttx/wdog.h | 100 ++++++++++++++++++++++++++++++ sched/clock/clock_abstime2ticks.c | 35 +++++++++++ 3 files changed, 157 insertions(+) diff --git a/include/nuttx/clock.h b/include/nuttx/clock.h index a589fb41d5..f56c9e6bd6 100644 --- a/include/nuttx/clock.h +++ b/include/nuttx/clock.h @@ -492,6 +492,28 @@ EXTERN volatile clock_t g_system_ticks; } \ while (0) +/**************************************************************************** + * Name: clock_realtime2absticks + * + * Description: + * Convert real time to monotonic ticks. + * + * Input Parameters: + * mono - Return the converted time here. + * abstime - Convert this absolute time to ticks + * + * Returned Value: + * OK (0) on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts should be disabled so that the time is not changing during + * the calculation + * + ****************************************************************************/ + +int clock_realtime2absticks(FAR const struct timespec *reltime, + FAR clock_t *absticks); + /**************************************************************************** * Name: clock_compare * diff --git a/include/nuttx/wdog.h b/include/nuttx/wdog.h index c3ac6b18bc..a548c5611e 100644 --- a/include/nuttx/wdog.h +++ b/include/nuttx/wdog.h @@ -27,6 +27,7 @@ #include +#include #include #include @@ -176,6 +177,105 @@ int wd_start(FAR struct wdog_s *wdog, sclock_t delay, int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks, wdentry_t wdentry, wdparm_t arg); +/**************************************************************************** + * Name: wd_start_abstime + * + * Description: + * This function adds a watchdog timer to the active timer queue. The + * specified watchdog function at 'wdentry' will be called from the + * interrupt level after the specified number of ticks has reached. + * Watchdog timers may be started from the interrupt level. + * + * Watchdog timers execute in the address environment that was in effect + * when wd_start() is called. + * + * Watchdog timers execute only once. + * + * To replace either the timeout delay or the function to be executed, + * call wd_start again with the same wdog; only the most recent wdStart() + * on a given watchdog ID has any effect. + * + * Input Parameters: + * wdog - Watchdog ID + * abstime - Absolute time with struct timespec + * 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. + * + ****************************************************************************/ + +#define wd_start_abstime(wdog, abstime, wdentry, arg) \ + wd_start_abstick(wdog, clock_time2ticks(abstime), wdentry, arg) + +/**************************************************************************** + * Name: wd_start_realtime + * + * Description: + * This function adds a watchdog timer to the active timer queue. The + * specified watchdog function at 'wdentry' will be called from the + * interrupt level after the specified number of ticks has reached. + * Watchdog timers may be started from the interrupt level. + * + * Watchdog timers execute in the address environment that was in effect + * when wd_start() is called. + * + * Watchdog timers execute only once. + * + * To replace either the timeout delay or the function to be executed, + * call wd_start again with the same wdog; only the most recent wdStart() + * on a given watchdog ID has any effect. + * + * Input Parameters: + * wdog - Watchdog ID + * realtime - Realtime with struct timespec + * 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. + * + ****************************************************************************/ + +static inline int wd_start_realtime(FAR struct wdog_s *wdog, + FAR const struct timespec *realtime, + wdentry_t wdentry, + wdparm_t arg) +{ +#ifdef CONFIG_CLOCK_TIMEKEEPING + irqstate_t flags; + clock_t ticks; + int ret; + + flags = enter_critical_section(); + clock_abstime2ticks(CLOCK_REALTIME, realtime, &ticks); + ret = wd_start(wdog, ticks, wdentry, arg); + leave_critical_section(flags); + + return ret; +#else + clock_t absticks; + + clock_realtime2absticks(realtime, &absticks); + return wd_start_abstick(wdog, absticks, wdentry, arg); +#endif +} + /**************************************************************************** * Name: wd_cancel * diff --git a/sched/clock/clock_abstime2ticks.c b/sched/clock/clock_abstime2ticks.c index 29a5af0d34..6a7b3f4e86 100644 --- a/sched/clock/clock_abstime2ticks.c +++ b/sched/clock/clock_abstime2ticks.c @@ -104,3 +104,38 @@ int clock_abstime2ticks(clockid_t clockid, return OK; } + +/**************************************************************************** + * Name: clock_realtime2absticks + * + * Description: + * Convert real time to monotonic ticks. + * + * Input Parameters: + * mono - Return the converted time here. + * abstime - Convert this absolute time to ticks + * + * Returned Value: + * OK (0) on success; a negated errno value on failure. + * + * Assumptions: + * Interrupts should be disabled so that the time is not changing during + * the calculation + * + ****************************************************************************/ + +int clock_realtime2absticks(FAR const struct timespec *reltime, + FAR clock_t *absticks) +{ +#ifndef CONFIG_CLOCK_TIMEKEEPING + struct timespec mono; + + clock_timespec_subtract(reltime, &g_basetime, &mono); + + *absticks = clock_time2ticks(&mono); + + return OK; +#else + return -ENOSYS; +#endif +}