From 55cfefd90a58e7e0d33e13714f21fb75a9718010 Mon Sep 17 00:00:00 2001 From: chenchaoqun Date: Mon, 27 Jul 2020 11:49:52 +0800 Subject: [add] switch default clause --- src/timer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/timer.c') diff --git a/src/timer.c b/src/timer.c index 28a5a9e494..4d12c7ec78 100644 --- a/src/timer.c +++ b/src/timer.c @@ -500,7 +500,10 @@ rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg) /*timer is stop*/ *(rt_tick_t *)arg = RT_TIMER_FLAG_DEACTIVATED; } - break; + break; + + default: + break; } return RT_EOK; -- cgit v1.3.1 From 76d1651a7463eb4bdf1215bd28dd289647fd11eb Mon Sep 17 00:00:00 2001 From: xieyangrun Date: Sat, 15 Aug 2020 20:15:29 +0800 Subject: fixed the iterator failure for softtimer list timeout check. --- src/timer.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'src/timer.c') diff --git a/src/timer.c b/src/timer.c index 4d12c7ec78..52707f2306 100644 --- a/src/timer.c +++ b/src/timer.c @@ -595,20 +595,19 @@ rt_tick_t rt_timer_next_timeout_tick(void) void rt_soft_timer_check(void) { rt_tick_t current_tick; - rt_list_t *n; struct rt_timer *t; RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n")); - current_tick = rt_tick_get(); - /* lock scheduler */ rt_enter_critical(); - for (n = rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next; - n != &(rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1]);) + while (!rt_list_isempty(&rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) { - t = rt_list_entry(n, struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]); + t = rt_list_entry(rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next, + struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - 1]); + + current_tick = rt_tick_get(); /* * It supposes that the new tick shall less than the half duration of @@ -618,9 +617,6 @@ void rt_soft_timer_check(void) { RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t)); - /* move node to the next */ - n = n->next; - /* remove timer from timer list firstly */ _rt_timer_remove(t); @@ -629,9 +625,6 @@ void rt_soft_timer_check(void) /* call timeout function */ t->timeout_func(t->parameter); - /* re-get tick */ - current_tick = rt_tick_get(); - RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t)); RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick)); -- cgit v1.3.1 From 1c6700acfdc6df71e14361d1c586ca32bb731e44 Mon Sep 17 00:00:00 2001 From: Bernard Xiong Date: Wed, 30 Sep 2020 23:50:18 +0800 Subject: [kernel] fix the timer issue --- src/timer.c | 85 +++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 27 deletions(-) (limited to 'src/timer.c') diff --git a/src/timer.c b/src/timer.c index 52707f2306..4b9003794c 100644 --- a/src/timer.c +++ b/src/timer.c @@ -25,6 +25,10 @@ static rt_list_t rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL]; #ifdef RT_USING_TIMER_SOFT + +#define RT_SOFT_TIMER_IDLE 1 +#define RT_SOFT_TIMER_BUSY 0 + #ifndef RT_TIMER_THREAD_STACK_SIZE #define RT_TIMER_THREAD_STACK_SIZE 512 #endif @@ -33,6 +37,8 @@ static rt_list_t rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL]; #define RT_TIMER_THREAD_PRIO 0 #endif +/* soft timer status */ +static rt_uint8_t soft_timer_status = RT_SOFT_TIMER_IDLE; /* soft timer list */ static rt_list_t rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL]; static struct rt_thread timer_thread; @@ -221,6 +227,8 @@ rt_err_t rt_timer_detach(rt_timer_t timer) level = rt_hw_interrupt_disable(); _rt_timer_remove(timer); + /* stop timer */ + timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -284,6 +292,8 @@ rt_err_t rt_timer_delete(rt_timer_t timer) level = rt_hw_interrupt_disable(); _rt_timer_remove(timer); + /* stop timer */ + timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* enable interrupt */ rt_hw_interrupt_enable(level); @@ -408,7 +418,8 @@ rt_err_t rt_timer_start(rt_timer_t timer) if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER) { /* check whether timer thread is ready */ - if ((timer_thread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND) + if ((soft_timer_status == RT_SOFT_TIMER_IDLE) && + ((timer_thread.stat & RT_THREAD_STAT_MASK) == RT_THREAD_SUSPEND)) { /* resume timer thread to check soft timer */ rt_thread_resume(&timer_thread); @@ -445,13 +456,12 @@ rt_err_t rt_timer_stop(rt_timer_t timer) level = rt_hw_interrupt_disable(); _rt_timer_remove(timer); + /* change status */ + timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* enable interrupt */ rt_hw_interrupt_enable(level); - /* change stat */ - timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; - return RT_EOK; } RTM_EXPORT(rt_timer_stop); @@ -467,10 +477,13 @@ RTM_EXPORT(rt_timer_stop); */ rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg) { + register rt_base_t level; + /* timer check */ RT_ASSERT(timer != RT_NULL); RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer); + level = rt_hw_interrupt_disable(); switch (cmd) { case RT_TIMER_CTRL_GET_TIME: @@ -505,6 +518,7 @@ rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg) default: break; } + rt_hw_interrupt_enable(level); return RT_EOK; } @@ -521,6 +535,7 @@ void rt_timer_check(void) struct rt_timer *t; rt_tick_t current_tick; register rt_base_t level; + rt_list_t list = RT_LIST_OBJECT_INIT(list); RT_DEBUG_LOG(RT_DEBUG_TIMER, ("timer check enter\n")); @@ -544,7 +559,12 @@ void rt_timer_check(void) /* remove timer from timer list firstly */ _rt_timer_remove(t); - + if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC)) + { + t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; + } + /* add timer to temporary list */ + rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); /* call timeout function */ t->timeout_func(t->parameter); @@ -554,6 +574,12 @@ void rt_timer_check(void) RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t)); RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick)); + /* Check whether the timer object is detached or started again */ + if (rt_list_isempty(&list)) + { + continue; + } + if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) { @@ -561,14 +587,8 @@ void rt_timer_check(void) t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; rt_timer_start(t); } - else - { - /* stop timer */ - t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; - } } - else - break; + else break; } /* enable interrupt */ @@ -589,18 +609,20 @@ rt_tick_t rt_timer_next_timeout_tick(void) #ifdef RT_USING_TIMER_SOFT /** - * This function will check timer list, if a timeout event happens, the + * This function will check software-timer list, if a timeout event happens, the * corresponding timeout function will be invoked. */ void rt_soft_timer_check(void) { rt_tick_t current_tick; struct rt_timer *t; + register rt_base_t level; + rt_list_t list = RT_LIST_OBJECT_INIT(list); RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n")); - /* lock scheduler */ - rt_enter_critical(); + /* disable interrupt */ + level = rt_hw_interrupt_disable(); while (!rt_list_isempty(&rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1])) { @@ -619,17 +641,32 @@ void rt_soft_timer_check(void) /* remove timer from timer list firstly */ _rt_timer_remove(t); + if (!(t->parent.flag & RT_TIMER_FLAG_PERIODIC)) + { + t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; + } + /* add timer to temporary list */ + rt_list_insert_after(&list, &(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); + + soft_timer_status = RT_SOFT_TIMER_BUSY; + /* enable interrupt */ + rt_hw_interrupt_enable(level); - /* not lock scheduler when performing timeout function */ - rt_exit_critical(); /* call timeout function */ t->timeout_func(t->parameter); RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t)); RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick)); - /* lock scheduler */ - rt_enter_critical(); + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + soft_timer_status = RT_SOFT_TIMER_IDLE; + /* Check whether the timer object is detached or started again */ + if (rt_list_isempty(&list)) + { + continue; + } if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) @@ -638,17 +675,11 @@ void rt_soft_timer_check(void) t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; rt_timer_start(t); } - else - { - /* stop timer */ - t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; - } } else break; /* not check anymore */ } - - /* unlock scheduler */ - rt_exit_critical(); + /* enable interrupt */ + rt_hw_interrupt_enable(level); RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n")); } -- cgit v1.3.1 From 7b28bc6edee6480559d5fc28c7addf2f0664426d Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Fri, 27 Nov 2020 10:33:36 +0800 Subject: Fixed an issue with rt_timer_start being broken and destroying the timer list --- src/timer.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/timer.c') diff --git a/src/timer.c b/src/timer.c index 4b9003794c..4d021ab367 100644 --- a/src/timer.c +++ b/src/timer.c @@ -331,7 +331,6 @@ rt_err_t rt_timer_start(rt_timer_t timer) _rt_timer_remove(timer); /* change status of timer */ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; - rt_hw_interrupt_enable(level); RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent))); @@ -342,9 +341,6 @@ rt_err_t rt_timer_start(rt_timer_t timer) RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2); timer->timeout_tick = rt_tick_get() + timer->init_tick; - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - #ifdef RT_USING_TIMER_SOFT if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER) { -- cgit v1.3.1 From 014105025a5c73a2aa58cd703ad157d29d5c6aff Mon Sep 17 00:00:00 2001 From: tangyuxin <462747508@qq.com> Date: Thu, 3 Dec 2020 09:43:09 +0800 Subject: [timer] Fix the bug that the linked list is still mounted when the single timer is not modified --- src/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/timer.c') diff --git a/src/timer.c b/src/timer.c index 4b9003794c..fc8053e90e 100644 --- a/src/timer.c +++ b/src/timer.c @@ -579,7 +579,7 @@ void rt_timer_check(void) { continue; } - + rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) { @@ -667,7 +667,7 @@ void rt_soft_timer_check(void) { continue; } - + rt_list_remove(&(t->row[RT_TIMER_SKIP_LIST_LEVEL - 1])); if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) && (t->parent.flag & RT_TIMER_FLAG_ACTIVATED)) { -- cgit v1.3.1