RT_Thread应用13—软件定时器1
第二十二 软件定时器(第一部分)
一、概念
定时器,是指从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可以自定义定时器的周期与频率。如:闹钟
超时函数需要注意:
- 需要快进快出
- 不能有任何阻塞线程运行的情况,如 rt_thread_delay()以及其它能阻塞线程运行的函数
- 两次触发超时函数的时间间隔 Tick 叫定时器的定时周期。
RT-Thread 软件定时器功能上支持:
-
静态裁剪:能通过宏关闭软件定时器功能。
-
软件定时器创建。
-
软件定时器启动。
-
软件定时器停止。
-
软件定时器删除。
二、应用场景
三、定时器的精度
-
软件定时器以系统节拍周期为计时单位。系统节拍是系统的心跳节拍,表示系统时钟的频率,类似于人的心跳,1s 能跳动多少下,系统节拍配置为 RT_TICK_PER_SECOND,默认是 1000。那么系统的时钟节拍周期就为 1ms(1s 跳动 1000 下,每一下就为 1ms)。
-
软件定时器的所定时数值必须是这个节拍周期的
整数倍
例如节拍周期是 10ms,那么上层软件定时器定时数值只能是 10ms,20ms,100ms 等,而不能取值为 15ms。 -
由于节拍定义了系统中定时器能够分辨的精确度,系统可以根据实际系统 CPU 的处理能力和实时性需求设置合适的数值,
————系统节拍周期的值越小,精度越高,但是系统开销也将越大
四、 软件定时器的运作机制
软件定时器是系统资源,创建定时器的时候会分配一块内存空间。
重要的全局变量:rt_tick:
它是一个 32 位无符号的变量,用于记录当前系统经过的 tick 时间,当硬件定时器中断来临时,它将自动增加 1。
软件定时器列表 rt_soft_timer_list:
系统新创建并**的定时器都会以超时时间****升序 的 方 式 插 入 到 列 表 中
例子:
在定时器链表中插入过程
问:系统如何处理软件定时器列表?
ANS:系统在不断运行, rt_tick 随着 SysTick 的触发一直在增长(每一次硬件定时器中断来临,rt_tick 变量会加 1),会比较当前系统时间 rt_tick 是否大于或等于 timeout。
若是则表示超时,定时器线程调用对应定时器的超时函数,否则退出软件定时器线程 。
如:在创建定 Timer1 并且启动后,假如系统经过了 50 个tick, rt_tick 从 0 增长到 50, rt_tick = Timer1 的 timeout 值, 这时会触发与 Timer1 对应的超
时函数,从而转到超时函数中执行用户代码,同时将 Timer1 从 rt_timer_list 删除。
在 rt_tick=40 的时候创建的 Timer3,在经过 130 个 tick 后(此时系统时间 rt_tick 是 40,130个 tick 就是系统时间 rt_tick 为 170 的时候),与 Timer3 定时器对应的超时函数会被触发,接着将 Timer3 从 rt_timer_list 删除。
需要注意:
- 软件定时器的超时函数中应快进快出,绝对不允许使用任何可能引软件定时器起线程挂起或者阻塞的 API 接口,在超时函数中也绝对不允许出现死循环。
- 软件定时器使用了系统的一个队列和一个线程资源,软件定时器线程的优先级默认为 RT_TIMER_THREAD_PRIO。
- 创建单次软件定时器,该定时器超时执行完超时函数后,系统会自动删除该软件定时器,并回收资源。
- 定时器线程的堆栈大小默认为 RT_TIMER_THREAD_STACK_SIZE,512 个字节。