diff --git a/include/rtthread.h b/include/rtthread.h index 13a1a4424b..d7be380764 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -138,6 +138,7 @@ rt_err_t rt_thread_delete(rt_thread_t thread); rt_err_t rt_thread_yield(void); rt_err_t rt_thread_delay(rt_tick_t tick); +rt_err_t rt_thread_delay_util(rt_tick_t *tick, rt_tick_t inc_tick); rt_err_t rt_thread_mdelay(rt_int32_t ms); rt_err_t rt_thread_control(rt_thread_t thread, int cmd, void *arg); rt_err_t rt_thread_suspend(rt_thread_t thread); diff --git a/src/thread.c b/src/thread.c index 7596906fae..95f9f76f84 100644 --- a/src/thread.c +++ b/src/thread.c @@ -530,6 +530,61 @@ rt_err_t rt_thread_delay(rt_tick_t tick) } RTM_EXPORT(rt_thread_delay); +/** + * This function will let current thread delay util (*tick + inc_tick). + * + * @param tick the tick of last wakeup. + * @param inc_tick the increment tick + * + * @return RT_EOK + */ +rt_err_t rt_thread_delay_util(rt_tick_t *tick, rt_tick_t inc_tick) +{ + register rt_base_t level; + struct rt_thread *thread; + + /* set to current thread */ + thread = rt_thread_self(); + RT_ASSERT(thread != RT_NULL); + RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread); + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + if (rt_tick_get() - *tick < inc_tick) + { + *tick = rt_tick_get() - *tick + inc_tick; + + /* suspend thread */ + rt_thread_suspend(thread); + + /* reset the timeout of thread timer and start it */ + rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, tick); + rt_timer_start(&(thread->thread_timer)); + + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + rt_schedule(); + + /* get the wakeup tick */ + *tick = rt_tick_get(); + + /* clear error number of this thread to RT_EOK */ + if (thread->error == -RT_ETIMEOUT) + { + thread->error = RT_EOK; + } + } + else + { + rt_hw_interrupt_enable(level); + } + + return RT_EOK; +} +RTM_EXPORT(rt_thread_delay_util); + /** * This function will let current thread delay for some milliseconds. *