rt-thread中软件定时器组件超时界限的一点理解
@2019-01-15
【小记】
对 rt-thread 中的软件定时器组件中超时界限的一点理解
rt_thread_timer_entry(void *parameter)函数中if ((next_timeout - current_tick) < RT_TICK_MAX / 2) --- 条件1
rt_soft_timer_check(void)函数中if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2) --- 条件2
举个特例:
假定某时刻
next_timeout = 0xFFFFFF00;
current_tick = 0x100;
next_timeout - current_tick = 0xFFFFFE00 < RT_TICK_MAX / 2 = 0x7FFFFFFF 条件1不成立
current_tick - t->timeout_tick = 0x200 < RT_TICK_MAX / 2 = 0x7FFFFFFF 条件2成立 (实际比0x200d大一点,因current_tick在增长)
这样则会出现定时器错误的定时到达而调用其回调函数,实际定时器计时还远未到
为避免以上情况出现,在函数 rt_timer_start(rt_timer_t timer) 中断言语句 RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2) 规定了延时长度(即MSB为0)
具体代码:
/**
* This function will check timer list, if a timeout event happens, the
* corresponding timeout function will be invoked.
*/
void rt_soft_timer_check(void)
{
rt_tick_t current_tick;
rt_list_t *n;
struct rt_timer *t; RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check enter\n")); current_tick = rt_tick_get(); /* lock scheduler */
rt_enter_critical(); for (n = rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - ].next;
n != &(rt_soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL - ]);)
{
t = rt_list_entry(n, struct rt_timer, row[RT_TIMER_SKIP_LIST_LEVEL - ]); /*
* It supposes that the new tick shall less than the half duration of
* tick max.
*/
if ((current_tick - t->timeout_tick) < RT_TICK_MAX / )
{
RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t)); /* move node to the next */
n = n->next; /* remove timer from timer list firstly */
_rt_timer_remove(t); /* not lock scheduler when performing timeout function */
rt_exit_critical();
/* call timeout function */
t->timeout_func(t->parameter); /* re-get tick */
current_tick = rt_tick_get(); RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));
RT_DEBUG_LOG(RT_DEBUG_TIMER, ("current tick: %d\n", current_tick)); /* lock scheduler */
rt_enter_critical(); if ((t->parent.flag & RT_TIMER_FLAG_PERIODIC) &&
(t->parent.flag & RT_TIMER_FLAG_ACTIVATED))
{
/* start it */
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
rt_timer_start(t);
}
else
{
/* stop timer */
t->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
}
}
else break; /* not check anymore */
} /* unlock scheduler */
rt_exit_critical(); RT_DEBUG_LOG(RT_DEBUG_TIMER, ("software timer check leave\n"));
} /* system timer thread entry */
static void rt_thread_timer_entry(void *parameter)
{
rt_tick_t next_timeout; while ()
{
/* get the next timeout tick */
next_timeout = rt_timer_list_next_timeout(rt_soft_timer_list);
if (next_timeout == RT_TICK_MAX)
{
/* no software timer exist, suspend self. */
rt_thread_suspend(rt_thread_self());
rt_schedule();
}
else
{
rt_tick_t current_tick; /* get current tick */
current_tick = rt_tick_get(); if ((next_timeout - current_tick) < RT_TICK_MAX / )
{
/* get the delta timeout tick */
next_timeout = next_timeout - current_tick;
rt_thread_delay(next_timeout);
}
} /* check software timer */
rt_soft_timer_check();
}
}
rt-thread中软件定时器组件超时界限的一点理解的更多相关文章
- Python中对于GIL全局解释器锁的一点理解
GIL全局解释器锁 python最初开发时,开发人只考虑到了单核CPU的,为解决多线程运算之间的数据完整性和状态同步选择了加锁的方式.即GIL锁. 而目前的CPU都有多个核心,在运行python的某个 ...
- 【STM32H7教程】第22章 STM32H7的SysTick实现多组软件定时器
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第22章 STM32H7的SysTick实现 ...
- 【TencentOS tiny】深度源码分析(8)——软件定时器
软件定时器的基本概念 TencentOS tiny 的软件定时器是由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受硬件定时器资源限制的定时器服务,本质上软件定时器的使用相当 ...
- 让你提前认识软件开发(21):C程序中的定时器
版权声明:本文为博主原创文章.对文章内容有不论什么意见或建议.欢迎与作者单独交流.作者QQ(微信):245924426. https://blog.csdn.net/zhouzxi/article/d ...
- μC/OS-II中使用软件定时器
在试着将μC/OS-II移植到ARM7芯片(LPC2138)上的过程中,发现使用OSTmrCreate创建的OSTmr始终都不能执行CallbackFunction,OS版本是v2.85,最后是这么解 ...
- 在vue组件中设置定时器和清除定时器
由于项目中难免会碰到需要实时刷新,无论是获取短信码,还是在支付完成后轮询获取当前最新支付状态,这时就需要用到定时器.但是,定时器如果不及时合理地清除,会造成业务逻辑混乱甚至应用卡死的情况,这个时就需要 ...
- STM32 + RT Thread OS 学习笔记[二]
串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1. 目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...
- Unity中的定时器与延时器
JavaScript中的定时器与延时器,分别是 setInterval.setTimeout,对应的清理函数是:clearInterval.clearTimeout. 而在Unity中,则分别是:In ...
- DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)
DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...
随机推荐
- 敏捷开发、DevOps相关书籍——书单
自己瞎整理的一些书单,都是豆瓣评分比较高的书,可以作为选择的一个参考. 书名 豆瓣链接 持续交付:发布可靠软件的系统方法 https://book.douban.com/subject/6862062 ...
- 分布式ID生成系统 UUID与雪花(snowflake)算法
Leaf——美团点评分布式ID生成系统 -https://tech.meituan.com/MT_Leaf.html 网游服务器中的GUID(唯一标识码)实现-基于snowflake算法-云栖社区-阿 ...
- Linux(CentOS7)命令学习摘要
1. 修改机器名 hostnamectl set-hostname newname 2. hosts主机存放位置 /etc/hosts 3. 安装tigervncserver, 然后使用vncserv ...
- Mybatis 配置resultMap一对多关联映射
resultMap配置: 引用: PO类: 接口: 测试: public class UserMapperTest { private SqlSessionFactory sqlSessionFact ...
- v-router几种定义方式
第一种 const router = new VueRouter({ routes: [{ path: '/newSongs', component: require('../views/NewSon ...
- npm --save-dev 和--save 参数的区别
npm中的--save与--save-dev参数的区别 --save一般规定把产品运行时(或生产环境)需要的npm包存入到package.json的dependencies中: --save-dev则 ...
- 神经网络-SGD-2
接上节: 3.梯度(gradient): def numerical_gradient(f,x): h=1e-5 grad=np.zeros_like(x) for index_x in range( ...
- 华硕X99-A II 安装使用 志强 XEON E5-1603 v4
刚开始无法启动,Debug灯的数字不停的轮回变换,后来把XMP开关关闭后,就能正常启动了.如果不行,就多关机几次,一般3次以上应该就可以启动开了.之后就能正常使用了.
- Sql Server 时间格式化
0 或 100 (*) 默认值 mon dd yyyy hh:miAM(或 PM) 1 101 美国 mm/dd/yyyy ...
- 【python练习题】程序14
#题目:将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. #我的方法应该比网上的更加简洁,只是递归可能速度慢 n = input('请输入一个正整数:') n = int(n) X ...