Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
[又出新作了]码农都能明白的rtt之timer
发布于 2012-11-24 19:39:40 浏览:3447
订阅该版
**码农都能明白的rtt之timer** 本文写给热爱rtt的广大童鞋们! 下面分析rtt的timer模块的code,有出错的地方请指正(xeonrun@gamil.com/Romeo)。 模块文件:src/timer.c 老规矩read the fucking source code! 下面分析三个核心的API,其它API不做分析。 ```void rt_timer_init(rt_timer_t timer, const char *name, void (*timeout)(void *parameter), void *parameter, rt_tick_t time, rt_uint8_t flag); rt_err_t rt_timer_start(rt_timer_t timer); void rt_timer_check(void);``` rt_timer_init: rt_timer_init或者creat接口都是初始化/创建一个timer。其作用就是使定时器超时后执行意见你指定的一个任务(timeout),这个定时器可以是周期性的(通过flag指定RT_TIMER_FLAG_PERIODIC)。其需要注意的是time参数不能大于32位无符号整数的一半,意思也就是最大小于31位无符号整数。 rt_timer_start: rt_timer_start是咱们分析的重点,先来看timer的结构: ``` struct rt_timer { struct rt_object parent; /**< inherit from rt_object */ rt_list_t list; /**< the node of timer list */ void (*timeout_func)(void *parameter); /**< timeout function */ void *parameter; /**< timeout function's parameter */ rt_tick_t init_tick; /**< timer timeout tick */ rt_tick_t timeout_tick; /**< timeout tick */ };``` 在初始化的时候会对init_tick进行指定多少个tick后超时,而timeout_tick记录了在start时当前的系统tick+init_tick的超时点。 可以看到有这么两句: ``` RT_ASSERT(timer->init_tick < RT_TICK_MAX/2); timer->timeout_tick = rt_tick_get() + timer->init_tick;``` 下面将要关注一个列表rt_timer_list。这个列表记录了当前系统中被start的timer。此时肯定也会将你新添加的timer放在这个列表的某个地方。 ``` for (n = timer_list->next; n != timer_list; n = n->next) { t = rt_list_entry(n, struct rt_timer, list); /* * It supposes that the new tick shall less than the half duration of * tick max. */ if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX/2) { rt_list_insert_before(n, &(timer->list)); break; } } /* no found suitable position in timer list */ if (n == timer_list) { rt_list_insert_before(n, &(timer->list)); }``` 以上代码段将会为新start的timer找到一个位置,为什么说‘找’呢?这是因为系统中timer很大的情况下,为了提供效率始终以最先超时的timer最为处理对象。不必每一个系统都去扫描一次整个rt_timer_list。 循环内部if中将会找一个比新start的timer后超时的timer,也就是插入排序以先超时优先条件。需要弄明白的是if的条件(t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX/2思考一下,我们的timeout_tick都是记录的相当于系统的tick往后走最大不超过 RT_TICK_MAX/2的,所以当前还在runing的timer肯定就是在系统当前tick的 RT_TICK_MAX/2辐射范围内的。所以如果用在runing的timeout_tick减去这个需要start的timer的timeout_tick。如果在runing的timer比需要start的timer的timeout_tick小的话(runing的timer先达到超时),肯定就是较小的数减一个较大数,那么相减的结果肯定就得大于RT_TICK_MAX/2。不成立继续往后找到一个反之条件成立的timer。当if条件成立时肯定就是在runing的timer的timeout_tick比需要start的timer的timeout_tick大。那么就将需要start的timer插入到这个timer的前面。如果整个循环都结束都没有找到一个timer比需要start的timer还要晚超时,那么就将把这个需要start的timer放在rt_timer_list的末尾。因为在runing的timer比这个要start的timer还要早超时。 rt_timer_check rt_timer_check这个函数将在系统tick中断函数rt_tick_increase中被调用,每一个系统tick都会用调用这个函数来扫描以超时的timer。当遇到第一个不超时的timer则推出扫描。所以整个timer的以优先超时条件做的插入排序非常牛叉! 当扫描过程中遇到一个已经超时的timer,先将它从rt_timer_list列表中移除,然后就会调用初始化时指定的timeout_func函数执行超时任务。 ``` /* remove timer from timer list firstly */ rt_list_remove(&(t->list)); /* call timeout function */ t->timeout_func(t->parameter);``` 如果此时检查到初始化时指定了flag的RT_TIMER_FLAG_PERIODIC选项。将会重新将timer调用start来加入runing列表rt_timer_list中。
查看更多
2
个回答
默认排序
按发布时间排序
geniusgogo
认证专家
2013-05-29
这家伙很懒,什么也没写!
其中 ``` RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2); ``` 应该可以修改成 ``` RT_ASSERT(timer->init_tick <= RT_TICK_MAX / 2); ```
撰写答案
登录
注册新账号
关注者
0
被浏览
3.4k
关于作者
geniusgogo
这家伙很懒,什么也没写!
提问
42
回答
157
被采纳
7
关注TA
发私信
相关问题
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
rt-thread 小内存算法源码分析
2
env中添加lvgl软件包后,keil编译包--c99错误
3
【NXP-MCXA153】 定时器驱动移植
4
GD32F450 看门狗驱动适配
5
【NXP-MCXA153】看门狗驱动移植
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
红枫
5
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
11
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部