RT-Thread定时器管理

刚开始学习RT-Thread定时器管理时,对系统初始化rtthread_startup()函数中的rt_system_timer_init()和rt_system_timer_thread_init()这两个和定时器有关的初始化函数功能不太了解,特别是两个函数中分别新建的rt_timer_list和rt_soft_timer_list这两个列表功能是什么不明白,现在在这里写一下个人见解,如有错误欢迎指正。

先说一个我的错误思路:最开始我以为rt_timer_list是管理硬件定时器列表,rt_soft_timer_list用来管理软件定时器列表,后面发现我错了,因为硬件定时器照理来说会引发中断,且精度一般远大于时间节拍,因此是不能被RT-Thread管理的;

我的改正思路:由于RT-Thread每一个线程都会有一个自带的软件定时器,当在线程中使用操作系统延时函数时会启动该线程软件定时器进行计时,所以rt_timer_list是用于管理线程软件定时器,rt_soft_timer_list则是用于管理用户自定义的软件定时器;

证明:

首先rt_soft_timer_list是用于管理用户自定义的软件定时器这一点根据下面的代码可以看出,因为有一个RT_USING_TIMER_SOFT宏是由用户在内核中进行手动开启/关闭的

然后看看rt_timer_list的作用,首先看任务创建(动态/静态)函数中都调用了_rt_thread_init()函数,而该函数中有初始化线程定时器函数:

同时线程控制块中也有对应定义:

因此我们可以确定每个线程都有一个线程软件定时器,我们再看看线程中经常会用到的延时函数rt_thread_sleep()中的函数实现有调用rt_timer_start(),

接下来我们看看rt_timer_start()函数的部分代码,如下:

该函数作用大概就是激活一个软件定时器,并把该定时器插入到对应的定时器管理列表中,并设置其超时时间。我们看下面有一个#ifdef  RT_USING_TIMER_SOFT宏,如果该定时器是用户自定义的软件定时器就插入rt_soft_timer_list,否则插入rt_timer_list,那rt_thread_sleep()挂起线程肯定不是插入rt_soft_timer_list,那只能是插入rt_timer_list,再结合线程自带的软件定时器,我们就能得出rt_timer_list是用于管理线程软件定时器;

/*******************关于软件定时器RT_TIMER_SKIP_LIST_LEVEL宏的作用*****************/

刚刚我们讲了RT-Thread把系统的软件定时器分为线程软件定时器和用户自定义软件定时器,并分别用一个列表来管理,那初始化时下面这个for循环是做什么的呢?

说实话下面这个图定义rt_timer_list[]的注释/* hard timer list*/有点让人误解是管理硬件定时器的,但我刚刚的分析认为这个其实也是管理软件定时器列表的,不过是线程软件定时器;这个hard timer list我认为可能的意思是,该类线程软件定时器的回调函数是发生在Systick硬件定时器中断中的,而自定义软件定时器回调函数是发生在软件定时器线程中的;

这个for循环和RT_TIMER_SKIP_LIST_LEVEL宏其实涉及到一个定时器跳表的概念,跳表是一种基于并联链表的数据结构,跳表是链表的一种,但它在链表的基础上增加了 “跳跃” 功能,正是这个功能,使得在查找元素时,跳表能够提供 O(log n)的时间复杂度;

例如:一个有序的链表,如下图所示,从该有序链表中搜索元素 {13, 39},需要比较的次数分别为 {3, 5},总共比较的次数为 3 + 5 = 8 次。

用跳表算法后可以采用类似二叉搜索树的方法,把一些节点提取出来作为索引,在这个结构里把 {3, 18,77} 提取出来作为一级索引,这样搜索的时候就可以减少比较次数了,得到如下图所示的结构:

在搜索的时候就减少比较次数,提升查找的效率,这是一种通过 “空间来换取时间” 的算法,在 RT-Thread 中通过宏定义 RT_TIMER_SKIP_LIST_LEVEL 来配置跳表的层数,默认为 1,表示采用一级有序链表图的有序链表算法,每增加一,表示在原链表基础上增加一级索引。

我们把包含所有定时器的链表叫做0层链表,定时器索引链表为1层或者2层...链表,那么我们应该如何确定索引链表中应该包含哪些定时器呢?这是由rtthread内核的定时器模块自己通过算法决定的,我们不需要管,该算法实现应该在下图rt_timer_start(rt_timer_t timer)函数中,我没细看(太垃圾了感觉看不懂,希望有大神发一个该算法的解析文章喂我嘴里,哈哈)

至此关于RT-thread的定时器管理的部分介绍就完成了,主要说明了rt_timer_list和rt_soft_timer_list的功能,还介绍了RT_TIMER_SKIP_LIST_LEVEL宏的功能,引入了跳表算法的概念;

参考文章:RT-Thread--时间管理 - 常瑟 - 博客园 (cnblogs.com)

  • 23
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。首先,RT-Thread是一个实时操作系统,它提供了一些基本的实时操作系统功能,例如线程、信号量、消息队列、定时器等。其中,定时器是一种非常重要的实时操作系统功能,它可以用来在指定的时间间隔内执行一些操作。 在RT-Thread中,定时器的实现是基于软件定时器,即在内核中维护一个定时器列表,每个定时器都有一个超时时间。当定时器到期时,内核会调用定时器回调函数来执行相应的操作。 下面是RT-Thread定时器的源码分析: 1. 定时器结构体 在RT-Thread中,定时器的结构体定义如下: ```c struct rt_timer { char name[RT_NAME_MAX]; /* 定时器名称 */ rt_list_t list; /* 定时器列表 */ rt_tick_t timeout_tick; /* 定时器超时时间 */ rt_tick_t init_tick; /* 定时器初始时间 */ rt_uint8_t flag; /* 定时器标志 */ rt_uint8_t state; /* 定时器状态 */ void (*timeout_func)(void* parameter); /* 定时器回调函数 */ void* parameter; /* 回调函数参数 */ }; ``` 可以看到,定时器结构体包含了定时器的名称、超时时间、标志、状态、回调函数等信息。 2. 定时器创建 在RT-Thread中,定时器的创建函数是rt_timer_create(),它的函数原型如下: ```c rt_err_t rt_timer_create(rt_timer_t *timer, const char *name, void (*timeout_func)(void* parameter), void* parameter, rt_tick_t time, rt_uint8_t flag); ``` 其中,timer表示定时器指针,name表示定时器名称,timeout_func表示定时器回调函数,parameter表示回调函数参数,time表示定时器超时时间,flag表示定时器标志。 rt_timer_create()函数会在内核中创建一个定时器,并将定时器添加到定时器列表中。如果创建成功,函数返回RT_EOK,否则返回错误码。 3. 定时器启动 在RT-Thread中,定时器的启动函数是rt_timer_start(),它的函数原型如下: ```c rt_err_t rt_timer_start(rt_timer_t timer); ``` rt_timer_start()函数会启动指定的定时器,并将其状态设置为RT_TIMER_FLAG_ACTIVATED。如果启动成功,函数返回RT_EOK,否则返回错误码。 4. 定时器停止 在RT-Thread中,定时器的停止函数是rt_timer_stop(),它的函数原型如下: ```c rt_err_t rt_timer_stop(rt_timer_t timer); ``` rt_timer_stop()函数会停止指定的定时器,并将其状态设置为RT_TIMER_FLAG_DEACTIVATED。如果停止成功,函数返回RT_EOK,否则返回错误码。 5. 定时器删除 在RT-Thread中,定时器的删除函数是rt_timer_delete(),它的函数原型如下: ```c rt_err_t rt_timer_delete(rt_timer_t timer); ``` rt_timer_delete()函数会删除指定的定时器,并释放相应的资源。如果删除成功,函数返回RT_EOK,否则返回错误码。 以上就是RT-Thread定时器的源码分析,希望能对你有所帮助。如果你有其他问题,可以继续问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值