Skip to content

Commit 3b111c8

Browse files
Fix-Pointxiaoxiang781216
authored andcommitted
sched/wdog: Refactor wdog module
This commit refactors the wdog module to use absolute time representation internally. The main improvements include: 1. Fixed recursive watchdog handling caused by calling wd_start within watchdog timeout callback function. 2. Simplified timer processing to improve performance and enhance code readability. 3. Improved accuracy of timers. 4. Reduced critical section and interrupt disable time, improving real-time performance. Signed-off-by: ouyangxiangzhen <[email protected]> Signed-off-by: ligd <[email protected]>
1 parent 7dabc6f commit 3b111c8

File tree

10 files changed

+336
-323
lines changed

10 files changed

+336
-323
lines changed

include/nuttx/clock.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,47 @@ void clock_timespec_subtract(FAR const struct timespec *ts1,
390390
FAR const struct timespec *ts2,
391391
FAR struct timespec *ts3);
392392

393+
/****************************************************************************
394+
* Name: clock_compare
395+
*
396+
* Description:
397+
* This function is used for check whether the expired time is reached.
398+
* It take the ticks wrap-around into consideration.
399+
*
400+
* Input Parameters:
401+
* tick1 - Expected time in clock ticks
402+
* tick2 - Current time in clock ticks
403+
*
404+
* Returned Value:
405+
* true - Expected ticks is timeout.
406+
* false - Otherwise.
407+
*
408+
* Assumptions:
409+
* The type of delay value should be sclock_t.
410+
*
411+
****************************************************************************/
412+
413+
/* clock_compare considers tick wraparound, discussed as follows:
414+
* Assuming clock_t is a 64-bit data type.
415+
*
416+
* Case 1: If tick2 - tick1 > 2^63, it is considered expired
417+
* or expired after tick2 wraparound.
418+
*
419+
* Case 2: If tick2 - tick1 <= 2^63,
420+
* it is considered not expired.
421+
*
422+
* For bit-63 as the sign bit, we can simplify this to:
423+
* (sclock_t)(tick2 - tick1) >= 0.
424+
*
425+
* However, this function requires an assumption to work correctly:
426+
* Assumes the timer delay time does not exceed SCLOCK_MAX (2^63 - 1).
427+
*
428+
* The range of the delay data type sclock_t being
429+
* [- (SCLOCK_MAX + 1), SCLOCK_MAX] ensures this assumption holds.
430+
*/
431+
432+
#define clock_compare(tick1, tick2) ((sclock_t)((tick2) - (tick1)) >= 0)
433+
393434
/****************************************************************************
394435
* Name: clock_isleapyear
395436
*

include/nuttx/wdog.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct wdog_s
8383
#ifdef CONFIG_PIC
8484
FAR void *picbase; /* PIC base address */
8585
#endif
86-
sclock_t lag; /* Timer associated with the delay */
86+
clock_t expired; /* Timer associated with the absoulute time */
8787
};
8888

8989
/****************************************************************************
@@ -137,6 +137,45 @@ extern "C"
137137
int wd_start(FAR struct wdog_s *wdog, sclock_t delay,
138138
wdentry_t wdentry, wdparm_t arg);
139139

140+
/****************************************************************************
141+
* Name: wd_start_absolute
142+
*
143+
* Description:
144+
* This function adds a watchdog timer to the active timer queue. The
145+
* specified watchdog function at 'wdentry' will be called from the
146+
* interrupt level after the specified number of ticks has reached.
147+
* Watchdog timers may be started from the interrupt level.
148+
*
149+
* Watchdog timers execute in the address environment that was in effect
150+
* when wd_start() is called.
151+
*
152+
* Watchdog timers execute only once.
153+
*
154+
* To replace either the timeout delay or the function to be executed,
155+
* call wd_start again with the same wdog; only the most recent wdStart()
156+
* on a given watchdog ID has any effect.
157+
*
158+
* Input Parameters:
159+
* wdog - Watchdog ID
160+
* ticks - Absoulute time in clock ticks
161+
* wdentry - Function to call on timeout
162+
* arg - Parameter to pass to wdentry.
163+
*
164+
* NOTE: The parameter must be of type wdparm_t.
165+
*
166+
* Returned Value:
167+
* Zero (OK) is returned on success; a negated errno value is return to
168+
* indicate the nature of any failure.
169+
*
170+
* Assumptions:
171+
* The watchdog routine runs in the context of the timer interrupt handler
172+
* and is subject to all ISR restrictions.
173+
*
174+
****************************************************************************/
175+
176+
int wd_start_absolute(FAR struct wdog_s *wdog, clock_t ticks,
177+
wdentry_t wdentry, wdparm_t arg);
178+
140179
/****************************************************************************
141180
* Name: wd_cancel
142181
*

sched/sched/sched.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ int nxsched_reprioritize(FAR struct tcb_s *tcb, int sched_priority);
340340
/* Support for tickless operation */
341341

342342
#ifdef CONFIG_SCHED_TICKLESS
343-
unsigned int nxsched_cancel_timer(void);
343+
clock_t nxsched_cancel_timer(void);
344344
void nxsched_resume_timer(void);
345345
void nxsched_reassess_timer(void);
346346
#else

sched/sched/sched_processtimer.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static inline void nxsched_process_scheduler(void)
157157
****************************************************************************/
158158

159159
#ifdef CONFIG_SMP
160-
static inline void nxsched_process_wdtimer(void)
160+
static inline void nxsched_process_wdtimer(clock_t ticks)
161161
{
162162
irqstate_t flags;
163163

@@ -171,11 +171,11 @@ static inline void nxsched_process_wdtimer(void)
171171
*/
172172

173173
flags = enter_critical_section();
174-
wd_timer();
174+
wd_timer(ticks);
175175
leave_critical_section(flags);
176176
}
177177
#else
178-
# define nxsched_process_wdtimer() wd_timer()
178+
# define nxsched_process_wdtimer(ticks) wd_timer(ticks)
179179
#endif
180180

181181
/****************************************************************************
@@ -236,7 +236,7 @@ void nxsched_process_timer(void)
236236

237237
/* Process watchdogs */
238238

239-
nxsched_process_wdtimer();
239+
nxsched_process_wdtimer(clock_systime_ticks());
240240

241241
#ifdef CONFIG_SYSTEMTICK_HOOK
242242
/* Call out to a user-provided function in order to perform board-specific,

0 commit comments

Comments
 (0)