From 5f076f3a0f2817eea5f859b9bee739b6f1fdaff8 Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Tue, 27 Jan 2026 10:38:22 +0800 Subject: [PATCH 1/2] sched/hrtimer: fix hrtimer regression introduced by recent update The hrtimer subsystem is independent of the OS tick mechanism and tickless mode. It must always be able to reprogram the hardware timer to achieve nanosecond-level resolution. A recent update restricted hardware timer reprogramming to tickless mode only. As a result, hrtimer no longer functions correctly when the scheduler is running in tick-based mode. This change removes the incorrect dependency on tickless mode and restores proper hrtimer operation. Signed-off-by: Chengdong Wang --- include/nuttx/arch.h | 7 ++++--- sched/hrtimer/hrtimer.h | 19 +++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index eaf14260eae50..b1172d00e5f71 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -2051,8 +2051,8 @@ int up_alarm_tick_cancel(FAR clock_t *ticks); * ****************************************************************************/ -#if defined(CONFIG_HRTIMER) || \ - defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM) +#if (defined(CONFIG_HRTIMER) && defined(CONFIG_ALARM_ARCH)) || \ + (defined(CONFIG_SCHED_TICKLESS) && defined(CONFIG_SCHED_TICKLESS_ALARM)) int up_alarm_start(FAR const struct timespec *ts); int up_alarm_tick_start(clock_t ticks); #endif @@ -2123,7 +2123,8 @@ int up_timer_tick_cancel(FAR clock_t *ticks); * ****************************************************************************/ -#if defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_ALARM) +#if (defined(CONFIG_HRTIMER) && defined(CONFIG_TIMER_ARCH)) || \ + (defined(CONFIG_SCHED_TICKLESS) && !defined(CONFIG_SCHED_TICKLESS_ALARM)) int up_timer_start(FAR const struct timespec *ts); int up_timer_tick_start(clock_t ticks); #endif diff --git a/sched/hrtimer/hrtimer.h b/sched/hrtimer/hrtimer.h index 606cd0863503e..2b6386910bd8a 100644 --- a/sched/hrtimer/hrtimer.h +++ b/sched/hrtimer/hrtimer.h @@ -122,26 +122,29 @@ void hrtimer_process(uint64_t now); * ns - Expiration time in nanoseconds. * * Returned Value: - * OK (0) on success, negated errno on failure. + * None. + * + * Assumptions: + * The underlying timer start function returns 0 on success. ****************************************************************************/ static inline_function void hrtimer_reprogram(uint64_t next_expired) { -#ifdef CONFIG_SCHED_TICKLESS - int ret; + int ret = 0; struct timespec ts; -# ifdef CONFIG_SCHED_TICKLESS_ALARM + clock_nsec2time(&ts, next_expired); + +#ifdef CONFIG_ALARM_ARCH ret = up_alarm_start(&ts); -# else +#else struct timespec current; up_timer_gettime(¤t); - clock_nsec2time(&ts, next_expired); clock_timespec_subtract(&ts, ¤t, &ts); ret = up_timer_start(&ts); -# endif - DEBUGASSERT(ret == 0); #endif + + DEBUGASSERT(ret == 0); } /**************************************************************************** From ec46504521745218a38d0d47c771c64b7cf66143 Mon Sep 17 00:00:00 2001 From: wangchengdong Date: Tue, 27 Jan 2026 11:01:28 +0800 Subject: [PATCH 2/2] sched/sched: enable OS tickless mode support using hrtimer Add support for running the OS in tickless mode with hrtimer, allowing the scheduler to operate without periodic ticks while maintaining high-resolution timer functionality. Signed-off-by: Chengdong Wang --- sched/sched/sched.h | 4 ++++ sched/sched/sched_timer.c | 10 ++++++++++ sched/wdog/wdog.h | 6 +++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sched/sched/sched.h b/sched/sched/sched.h index f126a3846e49a..db20164b90ec5 100644 --- a/sched/sched/sched.h +++ b/sched/sched/sched.h @@ -309,6 +309,10 @@ extern volatile spinlock_t g_cpu_tasklistlock; void nxsched_process_tick(void); +#if defined(CONFIG_HRTIMER) && defined(CONFIG_SCHED_TICKLESS) +int nxsched_hrtimer_tick_start(clock_t tick); +#endif + int nxthread_create(FAR const char *name, uint8_t ttype, int priority, FAR void *stack_addr, int stack_size, main_t entry, FAR char * const argv[], FAR char * const envp[]); diff --git a/sched/sched/sched_timer.c b/sched/sched/sched_timer.c index 9bf3c39aa8b67..e59b60debd079 100644 --- a/sched/sched/sched_timer.c +++ b/sched/sched/sched_timer.c @@ -108,6 +108,16 @@ nxsched_hrtimer_callback(FAR const struct hrtimer_s *hrtimer, * Public Functions ****************************************************************************/ +#if defined(CONFIG_HRTIMER) && defined(CONFIG_SCHED_TICKLESS) +int nxsched_hrtimer_tick_start(clock_t tick) +{ + return hrtimer_start(&g_sched_hrtimer, + nxsched_hrtimer_callback, + tick * NSEC_PER_TICK, + HRTIMER_MODE_ABS); +} +#endif + /**************************************************************************** * Name: nxsched_process_timer * diff --git a/sched/wdog/wdog.h b/sched/wdog/wdog.h index 8c924ad613573..41ed4807fa442 100644 --- a/sched/wdog/wdog.h +++ b/sched/wdog/wdog.h @@ -114,12 +114,16 @@ static inline_function clock_t wd_adjust_next_tick(clock_t tick) static inline_function void wd_timer_start(clock_t tick) { clock_t next_tick = wd_adjust_next_tick(tick); -#ifdef CONFIG_SCHED_TICKLESS_ALARM + +#ifdef CONFIG_HRTIMER + nxsched_hrtimer_tick_start(tick); +#elif defined(CONFIG_SCHED_TICKLESS_ALARM) up_alarm_tick_start(next_tick); #else up_timer_tick_start(next_tick - clock_systime_ticks()); #endif } + static inline_function void wd_timer_cancel(void) { struct timespec ts;