diff options
| author | xqyjlj <[email protected]> | 2023-07-26 14:54:04 +0800 |
|---|---|---|
| committer | guo <[email protected]> | 2023-07-27 11:35:29 +0800 |
| commit | 2b80fd38dc5357da59246c629223fe89bb10598a (patch) | |
| tree | 182ae9d291f680f650454a22c0e33cada41998ad /components/ktime/src/hrtimer.c | |
| parent | 0b93001f4f1391a8389a25d0dccddfe69c3d31d0 (diff) | |
🐞 fix(ktime/hrtimer): fix ctrl c
Diffstat (limited to 'components/ktime/src/hrtimer.c')
| -rw-r--r-- | components/ktime/src/hrtimer.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/components/ktime/src/hrtimer.c b/components/ktime/src/hrtimer.c index 81954c3e00..1b68c4ec80 100644 --- a/components/ktime/src/hrtimer.c +++ b/components/ktime/src/hrtimer.c @@ -51,6 +51,23 @@ rt_weak rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt, void (*timeout)( { static rt_timer_t timer = RT_NULL; + _outcb = timeout; + if (cnt == 0) + { + if (timer != RT_NULL) + { + if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) + { + rt_timer_stop(timer); + } + } + + if (_outcb) + _outcb(param); + + return RT_EOK; + } + if (timer == RT_NULL) { timer = rt_timer_create("shrtimer", _hrtimer_timeout, param, cnt, RT_TIMER_FLAG_ONE_SHOT); @@ -62,7 +79,6 @@ rt_weak rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt, void (*timeout)( rt_timer_control(timer, RT_TIMER_CTRL_SET_PARM, param); } - _outcb = timeout; if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) { rt_timer_stop(timer); @@ -79,11 +95,13 @@ rt_weak rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt, void (*timeout)( */ static unsigned long _cnt_convert(unsigned long cnt) { - int64_t count = cnt - rt_ktime_cputimer_getcnt(); - if (count <= 0) + unsigned long rtn = 0; + unsigned long count = cnt - rt_ktime_cputimer_getcnt(); + if (count > (_HRTIMER_MAX_CNT / 2)) return 0; - return (count * rt_ktime_cputimer_getres()) / rt_ktime_hrtimer_getres(); + rtn = (count * rt_ktime_cputimer_getres()) / rt_ktime_hrtimer_getres(); + return rtn == 0 ? 1 : rtn; /* at least 1 */ } static void _sleep_timeout(void *parameter) @@ -103,11 +121,15 @@ static void _timeout_callback(void *parameter) level = rt_spin_lock_irqsave(&_spinlock); _nowtimer = RT_NULL; rt_list_remove(&(timer->row)); - rt_spin_unlock_irqrestore(&_spinlock, level); if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) { + rt_spin_unlock_irqrestore(&_spinlock, level); timer->timeout_func(timer->parameter); } + else + { + rt_spin_unlock_irqrestore(&_spinlock, level); + } _set_next_timeout(); } @@ -117,10 +139,10 @@ static void _set_next_timeout(void) rt_ktime_hrtimer_t t; rt_base_t level; + level = rt_spin_lock_irqsave(&_spinlock); if (&_timer_list != _timer_list.prev) { - level = rt_spin_lock_irqsave(&_spinlock); - t = rt_list_entry((&_timer_list)->next, struct rt_ktime_hrtimer, row); + t = rt_list_entry((&_timer_list)->next, struct rt_ktime_hrtimer, row); if (_nowtimer != RT_NULL) { if (t != _nowtimer && t->timeout_cnt < _nowtimer->timeout_cnt) @@ -144,7 +166,8 @@ static void _set_next_timeout(void) else { _nowtimer = RT_NULL; - rt_ktime_hrtimer_settimeout(RT_NULL, RT_NULL, RT_NULL); + rt_spin_unlock_irqrestore(&_spinlock, level); + rt_ktime_hrtimer_settimeout(0, RT_NULL, RT_NULL); } } @@ -181,7 +204,8 @@ rt_err_t rt_ktime_hrtimer_delete(rt_ktime_hrtimer_t timer) /* parameter check */ RT_ASSERT(timer != RT_NULL); - level = rt_spin_lock_irqsave(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); + _nowtimer = RT_NULL; rt_list_remove(&timer->row); timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* stop timer */ rt_spin_unlock_irqrestore(&_spinlock, level); @@ -241,6 +265,7 @@ rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer) rt_spin_unlock_irqrestore(&_spinlock, level); return -RT_ERROR; } + _nowtimer = RT_NULL; rt_list_remove(&timer->row); timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* change status */ rt_spin_unlock_irqrestore(&_spinlock, level); @@ -325,7 +350,8 @@ rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer) /* parameter check */ RT_ASSERT(timer != RT_NULL); - level = rt_spin_lock_irqsave(&_spinlock); + level = rt_spin_lock_irqsave(&_spinlock); + _nowtimer = RT_NULL; rt_list_remove(&timer->row); /* stop timer */ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; |
