FreeRTOS学习笔记(三) 软件定时器管理

软件定时器能干嘛

软件定时器功能上和硬件定时器类似, 但是软件定时器是基于系统中断由软件来模拟的定时器

不像硬件定时器一样占用硬件资源

为了启用软件定时器,需要在头文件FreeRTOSConfig.h中设置configUSE_TIMERS的值为1

和硬件定时器相同, 在经过设定的tick数之后, 会调用对应的回调函数

可以在回调函数中实现需要的逻辑

注意不要在回调函数中执行任何可能会导致其进入阻塞状态的函数

因为定时器回调函数是由进程守护任务(RTOS daemon task)执行的

进程守护任务具有和正常任务相同的优先级机制

一旦定时器回调函数进入阻塞状态, 进程守护任务也会被阻塞, 这是不合法的

软件定时器分一次性定时器和自动重载定时器

一次性定时器在运行完一次之后自动进入休眠(dormant)状态

而自动重载定时器在执行完一次后会重新开始

8

既然定时器是由freertos守护进程任务维护的, 而启动定时器等api函数总是在别的任务中执行的

那么守护进程任务是如何知道在什么时候启动定时器, 又在什么时候对定时器进行操作呢

这就要提到上一节的队列了

队列作为一种任务间的通信方式, 理所应当能够作为进程守护任务与其他任务沟通的桥梁

当其他任务调用xTimerCreate()时, 会向Timer Command Queue(定时器任务列表)中发送一条指令

当进程守护任务从列表中读取到该指令时, 会执行相应的操作

1
2
3
4
5
TimerHandle_t xTimerCreate( const char * const pcTimerName,	//定时器名, 仅用于调试
const TickType_t xTimerPeriodInTicks, //定时器时间(tick数)
const BaseType_t xAutoReload, //是否自动重载 pdTRUE/pdFALSE
void * const pvTimerID, //定时器ID, 可用于自定义操作, 其他api函数本身不会使用
TimerCallbackFunction_t pxCallbackFunction ); //回调函数指针
1
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
1
void vTimerSetTimerID( const TimerHandle_t xTimer, void *pvNewID );
1
void *pvTimerGetTimerID( const TimerHandle_t xTimer );
1
2
3
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
TickType_t xNewPeriod,
TickType_t xTicksToWait );
1
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );

上述api函数如若要在中断中使用, 均需要使用其中断专用api函数, 函数名就是原函数名后面加上FromISR

例如xTimerStartFromISR()

静态创建软件定时器xTimerCreateStatic()