软件定时器是FreeRTOS中的一个重要模块,使用软件定时器可以方便的实现一些与超时或周期性相关的功能,本篇从FreeRTOS的源码入手,来分析FreeRTOS软件定时器的运行机理。
1 基础知识
硬件定时器
每次在定时时间到达之后就会自动触发一个中断,用户在中断服务函数中处理信息
硬件定时器的精度一般很高,可以达到纳秒级别
硬件定时器是芯片本身提供的定时功能
软件定时器
指定时间到达后要调用回调函数(也称超时函数),用户在回调函数中处理信息
硬件定时器的定时精度与系统时钟的周期有关,一般系统利用SysTick作为软件定时器的基础时钟,系统节拍配置为FreeRTOSConfig.h中的configTICK_RATE_HZ,默认是1000,那么系统的时钟节拍周期就为1ms
软件定时器是由操作系统提供的一类系统接口
注意:软件定时器回调函数的上下文是任务,回调函数要快进快出,且回调函数中不能有任何阻塞任务运行的情况,如vTaskDelay()以及其它能阻塞任务运行的函数。
1.2 软件定时器的两种工作模式FreeRTOS提供的软件定时器支持单次模式和周期模式
单次模式:当用户创建了定时器并启动了定时器后,定时时间到了,只执行一次回调函数之后就将该定时器删除,不再重新执行。
周期模式:这个定时器会按照设置的定时时间循环执行回调函数,直到用户将定时器删除
2软件定时器工作原理
通过查看FreeRTOS的源码,可以发现,软件定时器的运行原理实际是FreeRTOS 通过一个 prvTimerTask任务(也叫守护任务Daemon)管理软定时器,它是在启动调度器时自动创建的。另外,软件定时器在FreeRTOS中是可选功能,如果需要使用软件定时器,需要设置 FreeRTOSConfig.h 中的宏定义configUSE_TIMERS为1 。
先用一个图来表示整个创建过程:
下面来看一下启动调度器时是怎么创建Daemon任务的。
2.1 任务调度器函数创建Daemon任务main函数的最后会启动FreeRTOS的任务调度函数,在该函数中会创建软件定时器任务(即Daemon守护任务),并且可以看到是通过宏定义的方式选择编译:
xTimerCreateTimerTask()只是一个函数名,它内部的函数内容如下。