软件定时器能干嘛
软件定时器功能上和硬件定时器类似, 但是软件定时器是基于系统中断由软件来模拟的定时器
不像硬件定时器一样占用硬件资源
为了启用软件定时器,需要在头文件FreeRTOSConfig.h中设置configUSE_TIMERS的值为1
和硬件定时器相同, 在经过设定的tick数之后, 会调用对应的回调函数
可以在回调函数中实现需要的逻辑
注意不要在回调函数中执行任何可能会导致其进入阻塞状态的函数
因为定时器回调函数是由进程守护任务(RTOS daemon task)执行的
进程守护任务具有和正常任务相同的优先级机制
一旦定时器回调函数进入阻塞状态, 进程守护任务也会被阻塞, 这是不合法的
软件定时器分一次性定时器和自动重载定时器
一次性定时器在运行完一次之后自动进入休眠(dormant)状态
而自动重载定时器在执行完一次后会重新开始

既然定时器是由freertos守护进程任务维护的, 而启动定时器等api函数总是在别的任务中执行的
那么守护进程任务是如何知道在什么时候启动定时器, 又在什么时候对定时器进行操作呢
这就要提到上一节的队列了
队列作为一种任务间的通信方式, 理所应当能够作为进程守护任务与其他任务沟通的桥梁
当其他任务调用xTimerCreate()时, 会向Timer Command Queue(定时器任务列表)中发送一条指令
当进程守护任务从列表中读取到该指令时, 会执行相应的操作
1 | TimerHandle_t xTimerCreate( const char * const pcTimerName, //定时器名, 仅用于调试 |
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 | BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, |
1 | BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); |
上述api函数如若要在中断中使用, 均需要使用其中断专用api函数, 函数名就是原函数名后面加上FromISR
例如xTimerStartFromISR()
静态创建软件定时器xTimerCreateStatic()