From 86030f25b34c8648605fc62dd4b71644fd8a134d Mon Sep 17 00:00:00 2001 From: yueling hu <502966985@qq.com> Date: Thu, 5 Jun 2025 13:08:12 +0800 Subject: [PATCH 1/3] fix timer overflow --- src/ipc.c | 38 ++++++++++++++++++-------------------- src/mempool.c | 3 ++- src/thread.c | 15 +++++++++------ src/timer.c | 6 +++--- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/ipc.c b/src/ipc.c index 35c0146dd33..ca971c49f3b 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -46,6 +46,8 @@ * 2022-10-16 Bernard add prioceiling feature in mutex * 2023-04-16 Xin-zheqi redesigen queue recv and send function return real message size * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable + * 2025-06-01 htl5241 fix timer overflow + * */ #include @@ -2567,7 +2569,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; /* parameter check */ @@ -2578,7 +2580,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -2622,7 +2624,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mb_send_wait: start timer of thread:%s", thread->parent.name); @@ -2650,8 +2652,7 @@ static rt_err_t _rt_mb_send_wait(rt_mailbox_t mb, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -2846,7 +2847,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo { struct rt_thread *thread; rt_base_t level; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; /* parameter check */ @@ -2857,7 +2858,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -2902,7 +2903,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mb_recv: start timer of thread:%s", thread->parent.name); @@ -2930,8 +2931,7 @@ static rt_err_t _rt_mb_recv(rt_mailbox_t mb, rt_ubase_t *value, rt_int32_t timeo /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -3382,7 +3382,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, { rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; struct rt_thread *thread; rt_err_t ret; @@ -3402,7 +3402,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, return -RT_ERROR; /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); @@ -3447,7 +3447,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("mq_send_wait: start timer of thread:%s", thread->parent.name); @@ -3475,8 +3475,7 @@ static rt_err_t _rt_mq_send_wait(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } @@ -3765,7 +3764,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, struct rt_thread *thread; rt_base_t level; struct rt_mq_message *msg; - rt_uint32_t tick_delta; + rt_uint32_t tick_stamp; rt_err_t ret; rt_size_t len; @@ -3781,7 +3780,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0); /* initialize delta tick */ - tick_delta = 0; + tick_stamp = 0; /* get current thread */ thread = rt_thread_self(); RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(mq->parent.parent))); @@ -3826,7 +3825,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, if (timeout > 0) { /* get the start tick of timer */ - tick_delta = rt_tick_get(); + tick_stamp = rt_tick_get(); LOG_D("set thread:%s to timer list", thread->parent.name); @@ -3855,8 +3854,7 @@ static rt_ssize_t _rt_mq_recv(rt_mq_t mq, /* if it's not waiting forever and then re-calculate timeout tick */ if (timeout > 0) { - tick_delta = rt_tick_get() - tick_delta; - timeout -= tick_delta; + timeout -= rt_tick_get_delta(tick_stamp); if (timeout < 0) timeout = 0; } diff --git a/src/mempool.c b/src/mempool.c index 28bdb6cf896..3cc7b4517e0 100644 --- a/src/mempool.c +++ b/src/mempool.c @@ -17,6 +17,7 @@ * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to mempool.c * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix spinlock assert + * 2025-06-01 htl5241 fix timer overflow */ #include @@ -335,7 +336,7 @@ void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time) if (time > 0) { - time -= rt_tick_get() - before_sleep; + time -= rt_tick_get_delta(before_sleep); if (time < 0) time = 0; } diff --git a/src/thread.c b/src/thread.c index ed9dca13b61..e7a8362215a 100644 --- a/src/thread.c +++ b/src/thread.c @@ -35,6 +35,8 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2023-12-10 xqyjlj fix thread_exit/detach/delete * fix rt_thread_delay + * 2025-06-01 htl5241 fix timer overflow + * */ #include @@ -692,7 +694,6 @@ RTM_EXPORT(rt_thread_delay); rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) { struct rt_thread *thread; - rt_tick_t cur_tick; rt_base_t critical_level; RT_ASSERT(tick != RT_NULL); @@ -708,13 +709,15 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) /* disable interrupt */ critical_level = rt_enter_critical(); - cur_tick = rt_tick_get(); - if (cur_tick - *tick < inc_tick) + if (rt_tick_get_delta(*tick) < inc_tick) { rt_tick_t left_tick; + rt_tick_t target_tick; + target_tick = *tick + inc_tick; + left_tick = target_tick - rt_tick_get(); - *tick += inc_tick; - left_tick = *tick - cur_tick; + if (left_tick > target_tick) + left_tick = RT_TICK_MAX - left_tick + 1; /* suspend thread */ rt_thread_suspend_with_flag(thread, RT_UNINTERRUPTIBLE); @@ -735,7 +738,7 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) } else { - *tick = cur_tick; + *tick = rt_tick_get(); rt_exit_critical_safe(critical_level); } diff --git a/src/timer.c b/src/timer.c index ae6da29f760..ee8ef304047 100644 --- a/src/timer.c +++ b/src/timer.c @@ -22,6 +22,8 @@ * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable * 2024-01-25 Shell add RT_TIMER_FLAG_THREAD_TIMER for timer to sync with sched * 2024-05-01 wdfk-prog The rt_timer_check and _soft_timer_check functions are merged + * 2025-06-01 htl5241 remove redundancy + * fix timer overflow */ #include @@ -494,8 +496,6 @@ static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock) level = rt_spin_lock_irqsave(lock); - current_tick = rt_tick_get(); - rt_list_init(&list); while (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) @@ -762,7 +762,7 @@ void rt_timer_check(void) rt_tick_t next_timeout; ret = _timer_list_next_timeout(_soft_timer_list, &next_timeout); - if ((ret == RT_EOK) && (next_timeout <= rt_tick_get())) + if ((ret == RT_EOK) && ((rt_tick_get() - next_timeout) < RT_TICK_MAX / 2)) { rt_sem_release(&_soft_timer_sem); } From 21432f13c6c795f1a3e181a7d8511626216f22f4 Mon Sep 17 00:00:00 2001 From: yueling hu <502966985@qq.com> Date: Thu, 5 Jun 2025 15:23:02 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/thread.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/thread.c b/src/thread.c index e7a8362215a..a06f137febd 100644 --- a/src/thread.c +++ b/src/thread.c @@ -712,11 +712,10 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) if (rt_tick_get_delta(*tick) < inc_tick) { rt_tick_t left_tick; - rt_tick_t target_tick; - target_tick = *tick + inc_tick; - left_tick = target_tick - rt_tick_get(); + *tick = *tick + inc_tick; + left_tick = *tick - rt_tick_get(); - if (left_tick > target_tick) + if (left_tick > *tick) left_tick = RT_TICK_MAX - left_tick + 1; /* suspend thread */ From 6ae7c43392727f2747c588f91414a1d7b1dd2466 Mon Sep 17 00:00:00 2001 From: yueling hu <502966985@qq.com> Date: Thu, 5 Jun 2025 15:44:01 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/thread.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/thread.c b/src/thread.c index a06f137febd..63f026a0797 100644 --- a/src/thread.c +++ b/src/thread.c @@ -712,7 +712,8 @@ rt_err_t rt_thread_delay_until(rt_tick_t *tick, rt_tick_t inc_tick) if (rt_tick_get_delta(*tick) < inc_tick) { rt_tick_t left_tick; - *tick = *tick + inc_tick; + + *tick += inc_tick; left_tick = *tick - rt_tick_get(); if (left_tick > *tick)