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等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...
随机推荐
- stark组件之pop页面,按钮,url,页面
1.Window open() 方法 2.admin的pop添加按钮 3.stark之pop功能 3.知识点总结 4.coding代码 1.Window open() 方法 效果图 2.adm ...
- Docker -d : Running modprobe bridge nf_nat failed with message: exit status 1
nf_nat 是做什么用的 - DockOne.iohttp://dockone.io/question/1384 docker-py的配置与使用 - openxxs - 博客园http://www. ...
- JAVAString初始化的引用问题
1 String a="Hello JAVA"; 2 3 String b=a; 4 5 System.out.println(a); 6 7 System.out.println ...
- 6-2 Verbs and Adjectives with that clauses
1 Many sentences in English contain two clauses: a main clause and a "that" clause. The &q ...
- KVM+QEMU虚拟化概念
概念: KVM,即Kernel-basedvirtual machine,由redhat开发,是一种开源.免费的虚拟化技术.对企业来说,是一种可选的虚拟化解决方案. 定义:基于Linux内核的虚拟机 ...
- 集合之LinkedHashMap(含JDK1.8源码分析)
一.前言 大多数的情况下,只要不涉及线程安全问题,map都可以使用hashMap,不过hashMap有一个问题,hashMap的迭代顺序不是hashMap的存储顺序,即hashMap中的元素是无序的. ...
- Yii2后台管理系统常规单据模块最佳实践
后台管理系统的常规单据通常包括数据,页面,功能:其中数据,页面,功能又可以细分如下: 分类 二级分类 主要内容 注意事项 例如 数据 数据库迁移脚本 用于数据表生成及转态回滚 1.是否需要增 ...
- 洛谷 p1092 虫食算
题目链接: https://www.luogu.org/problemnew/show/P1092 这个题折腾了我好久 这其实本质上是一道凑算式的题目 ,让一个二维数组存算式,一个一位数组存字母分别代 ...
- cookie的域,路径
Cookie 的路径以及 Cookie 域 cookie 路径 cookie 一般都是由于用户访问页面而被创建的,可是并不是只有在创建 cookie 的页面才可以访问这个cookie.在默认情况下,出 ...
- 学习 Spring (二) Spring 注入
Spring入门篇 学习笔记 常用的两种注入方式 设值注入 构造注入 示例准备工作 添加 InjectionDAO: public interface InjectionDAO { void save ...