一、软件定时器(Software Timer)
软件定时器是一种由内核提供的纯软件实现的定时任务管理机制,其本质是通过系统时钟节拍(Tick)模拟定时功能,而非依赖硬件定时器。
1.基于系统 Tick
定时器的计时依赖 FreeRTOS 的系统时钟中断(通常由硬件定时器触发),每次 Tick 中断会更新定时器的计数值。
2.定时器服务任务(Daemon Task)
定时器的回调函数在独立的定时器服务任务中执行,该任务由 FreeRTOS 内核自动创建和管理。
3.动态管理
定时器可动态创建、启动、停止或删除,支持单次(One-Shot)和周期(Auto-Reload)两种模式。
4.工作原理
(1)定时器服务任务
该任务通过阻塞去等待定时器队列中的命令(如启动/停止定时器)或等待下一个定时器到期。
(2)定时器队列
用户通过 API发送命令到定时器命令队列,服务任务处理这些命令。
定时器状态(如剩余时间、周期模式)由服务任务维护。
(3)超时处理流程
每次系统 Tick 中断,内核检查定时器列表,更新剩余时间。
当定时器超时,服务任务调用其回调函数。
注意:回调函数在服务任务上下文中运行,需避免阻塞或长时间操作!
5.实际应用
//定时器回调函数
void vTimerCallback(TimerHandle_t xTimer) {
static int count = 0;
count++;
printf("Timer triggered! Count: %d\n", count);
}
// 创建定时器(周期模式,周期1000 Tick)
TimerHandle_t xTimer = xTimerCreate(
"PeriodicTimer", // 定时器名称
1000, // 周期(Tick数)
pdTRUE, // 自动重载(周期性)
NULL, // 定时器ID(可传递参数)
vTimerCallback // 回调函数
);
// 启动定时器(若在任务中调用,需指定阻塞时间)
if (xTimerStart(xTimer, 0) != pdPASS) {
// 启动失败处理
}
二、定时器服务任务和定时器
1. 调度器与定时器服务任务的关系
调度器启动时,FreeRTOS 会初始化内核基础设施,包括:
- 空闲任务(Idle Task):必须存在,用于处理空闲状态。
- 定时器服务任务(即守护任务):仅在配置启用时自动创建。
// FreeRTOSConfig.h 中需配置:
#define configUSE_TIMERS 1 // 启用软件定时器功能
#define configTIMER_TASK_PRIORITY (优先级) // 守护任务优先级
#define configTIMER_QUEUE_LENGTH (队列长度) // 定时器命令队列大小
2.软件定时器的创建
定时器服务任务 ≠ 用户定时器:
定时器服务任务是内核管理的后台任务,负责处理定时器的超时事件和命令队列。
用户自定义的软件定时器(如通过 xTimerCreate() 创建的定时器)不会自动创建,必须由开发者显式创建并启动。