用阻塞延时的方法实现线程缺点很明显,每个循环周期都要扫描所有线程,费时效率低。RT-Thread提供了更合理的选择,每个线程都内置一个定时器,使用时先将线程挂起,之后内置定时器启动并将定时器插入到全局的系统定时器列表rt_timer_list,它维护着一条双向链表,每个节点表示正在延时的定时器,节点按照延时大小升序排列,由SysTick中断来控制扫描系统定时器列表判断时间是否到了。如果排在第一个定时器时间没到,那么它之后的一定也没到(节点按照延时大小升序排列的),如果时间到了就让对应的线程就绪,这种方法大大缩短了寻找延时到期线程的时间。
1.系统定时器在timer.c中,需要添加到工程的srtt/source组中
/* hard timer list */
static rt_list_t rt_timer_list[RT_TIMER_SKIP_LIST_LEVEL];
2.系统定时器列表初始化由函数void rt_system_timer_init(void)完成,在timer.c中。
3.定时器统一由一个定时器结构体struct在rtdef.h里来定义。
/*** timer structure*/
struct rt_timer
{
struct rt_object parent; /**< inherit from rt_object */
rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL];
。。。。。
};
typedef struct rt_timer *rt_timer_t;
4.另外每个线程都会内置一个定时器,就是在线程控制块中添加一个定时器成员。
/*** Thread structure*/
struct rt_thread
{。。。
struct rt_timer thread_timer; /**< built-in thread timer */
。。。。
};
typedef struct rt_thread *rt_thread_t;5.定时器初始化由函数void rt_timer_init(rt_timer_t timer。。。)完成,在timer.c中。
6.与定时器相关的还有函数rt_timer_control()用于设置不同的初始值和状态,在timer.c中。
rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void *arg)
{
/* timer check */
RT_ASSERT(timer != RT_NULL);
switch (cmd)
{
case RT_TIMER_CTRL_GET_TIME:
*(rt_tick_t *)arg = timer->init_tick;
break;
。。。。
}
return RT_EOK;
}
RTM_EXPORT(rt_timer_control);
暂时只学习到这了,RT-Thread定时器要看的内容还是比较多的。
此内容由EEWORLD论坛网友qi777ji原创,如需转载或用于商业用途需征得作者同意并注明出处
本帖最后由 qi777ji 于 2019-4-25 12:53 编辑