(三)RT-Thread时钟与定时器管理
·
RT-Thread时钟与定时器管理 — 时间管理的艺术
前言
时间管理是RTOS的核心能力之一。RT-Thread通过时钟节拍驱动系统运转,通过定时器实现延时触发和周期任务。本文将介绍时钟节拍的概念、定时器的分类与使用方法,以及高精度延时的实现。
一、时钟节拍(OS Tick)
1.1 什么是时钟节拍?
时钟节拍是RT-Thread中最小的时间单位,类似于闹钟的"滴答"声。每一次"滴答",系统就前进一个时间单位。
时钟节拍的时间间隔由宏 RT_TICK_PER_SECOND 决定:
- 若
RT_TICK_PER_SECOND = 100,则每秒100次节拍,每个节拍 = 10ms - 若
RT_TICK_PER_SECOND = 1000,则每秒1000次节拍,每个节拍 = 1ms
1.2 时钟节拍的产生
时钟节拍依赖硬件定时器中断。以 STM32 的 SysTick 为例:
void SysTick_Handler(void)
{
rt_interrupt_enter(); // 进入中断
rt_tick_increase(); // 系统时钟+1
rt_interrupt_leave(); // 退出中断
}
每次 rt_tick_increase() 被调用,全局变量 rt_tick 自增1,记录系统从启动以来经历的总节拍数。
1.3 获取当前时钟节拍
rt_tick_t rt_tick_get(void);
通过在任务前后各获取一次 rt_tick 值,相减即可计算任务执行耗时:
rt_tick_t start = rt_tick_get();
// ... 执行某些操作 ...
rt_tick_t elapsed = rt_tick_get() - start;
rt_kprintf("耗时: %d ticks\n", elapsed);
二、定时器管理
定时器可以在指定时间后自动触发回调函数,就像家中的厨房定时器——时间到了就提醒你。
2.1 硬件定时器 vs 软件定时器
| 类型 | 精度 | 实现方式 | 适用场景 |
|---|---|---|---|
| 硬件定时器 | 纳秒级 | 硬件直接提供 | 电机控制等高精度场景 |
| 软件定时器 | 依赖OS Tick | 操作系统管理 | 一般延时任务,灵活易用 |
2.2 定时器的分类
按触发方式分:
- 单次触发定时器:触发一次后自动停止,如一次性闹钟。
- 周期触发定时器:周期性重复触发,如每日闹钟。
按执行上下文分:
- 硬件模式(HARD_TIMER):回调在中断上下文中执行,响应极快,但回调函数必须简短。
- 软件模式(SOFT_TIMER):回调在
timer线程中执行,可以做更复杂的操作。
2.3 创建定时器
rt_timer_t rt_timer_create(const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag);
| 参数 | 说明 |
|---|---|
name |
定时器名称 |
timeout |
超时回调函数 |
parameter |
传递给回调函数的参数 |
time |
定时时长,单位为 OS Tick |
flag |
定时器类型标志 |
flag 常用值:
RT_TIMER_FLAG_ONE_SHOT:单次触发RT_TIMER_FLAG_PERIODIC:周期触发RT_TIMER_FLAG_HARD_TIMER:硬件模式RT_TIMER_FLAG_SOFT_TIMER:软件模式
2.4 启动与停止定时器
rt_err_t rt_timer_start(rt_timer_t timer); // 启动
rt_err_t rt_timer_stop(rt_timer_t timer); // 停止
rt_err_t rt_timer_delete(rt_timer_t timer); // 删除
三、定时器使用示例
以下示例创建一个周期定时器和一个单次定时器:
#include <rtthread.h>
static rt_timer_t timer1; // 周期定时器
static rt_timer_t timer2; // 单次定时器
/* 周期定时器回调 */
static void timeout1(void *parameter)
{
rt_kprintf("Periodic timer timeout\n");
}
/* 单次定时器回调 */
static void timeout2(void *parameter)
{
rt_kprintf("One-shot timer timeout\n");
}
int main(void)
{
/* 创建周期定时器,每10个tick触发一次 */
timer1 = rt_timer_create("timer1", timeout1,
RT_NULL, 10,
RT_TIMER_FLAG_PERIODIC);
if (timer1 != RT_NULL)
rt_timer_start(timer1);
/* 创建单次定时器,30个tick后触发一次 */
timer2 = rt_timer_create("timer2", timeout2,
RT_NULL, 30,
RT_TIMER_FLAG_ONE_SHOT);
if (timer2 != RT_NULL)
rt_timer_start(timer2);
return 0;
}
运行效果:
timer1每 10 个 tick 输出一次 “Periodic timer timeout”timer2在第 30 个 tick 输出一次 “One-shot timer timeout” 后停止
四、控制定时器
通过 rt_timer_control() 可以动态修改定时器属性:
rt_err_t rt_timer_control(rt_timer_t timer, rt_uint8_t cmd, void *arg);
| 命令 | 说明 |
|---|---|
RT_TIMER_CTRL_SET_TIME |
修改超时时间 |
RT_TIMER_CTRL_SET_ONESHOT |
设置为单次定时器 |
RT_TIMER_CTRL_SET_PERIODIC |
设置为周期定时器 |
示例——将定时器超时时间改为50个tick:
rt_tick_t new_time = 50;
rt_timer_control(timer1, RT_TIMER_CTRL_SET_TIME, &new_time);
五、高精度延时
当需要比 OS Tick 更精确的延时(如微秒级),可以利用硬件定时器。以 ARM Cortex-M 的 SysTick 为例:
void rt_hw_us_delay(rt_uint32_t us)
{
rt_uint32_t ticks = us * (SysTick->LOAD / 1000000);
rt_uint32_t start = SysTick->VAL;
while ((SysTick->VAL - start) < ticks);
}
注意:高精度延时使用忙等待,仅适用于极短时间的精确延时场景,不应在常规逻辑中大量使用。
总结
| 要点 | 内容 |
|---|---|
| 时钟节拍 | 系统最小时间单位,由 RT_TICK_PER_SECOND 配置 |
| 定时器类型 | 单次触发 / 周期触发 |
| 执行模式 | 硬件模式(中断上下文)/ 软件模式(线程上下文) |
| 核心API | rt_timer_create → rt_timer_start → rt_timer_stop |
| 高精度延时 | 通过 SysTick 等硬件实现微秒级延时 |
掌握时钟与定时器,你就能精确控制任务的执行时机。下一篇将进入RTOS最核心的机制——线程间同步与通信。
更多推荐



所有评论(0)