1,要使用软件定时器,将timers.c编译进工程,然后将configUSE_TIMERS宏设置为1。
2,软件定时器的回调函数原型如下:
注意:回调函数要短,不能使任务进入阻塞状态。
3,软件定时器有两种状态:dormant和running
自动重装载的软件定时器的状态转换图如下:
一次性软件定时器的状态转换图如下:
4,软件定时器的回调函数时在定时器守护进程(RTOS daemon /‘timer service’ task)里面进行执行 。该进程是在启动系统调度的时候,FreeRTOS内核自动创建。通过配置宏configTIMER_TASK_PRIORITY和configTIMER_TASK_STACK_DEPTH设置该进程的任务优先级和任务栈大小。回调函数进入阻塞状态会导致守护进程进入阻塞状态,故不允许回调函数进入阻塞状态。
5,软件定时器的API函数通过命令队列与守护进程进行通信,其中命令队列的大小由宏configTIMER_QUEUE_LENGTH进行配置。
当调用API函数的任务优先级高于守护进程的优先级时,执行模式如下:
当调用API函数的任务优先级低于守护进程的优先级时,执行模式如下:
为了解决上面可能出现的问题,调用API函数时,在发送命令时,会同时发送时间戳。该时间戳用于确保定时器在发送命令的时间周期后,定时器到期,而不是守护进程处理命令后的时间到期。
6,定时器API函数
软件定时有一个ID,该ID是一个void*类型,可以存储整形值,指向任何变量,用作函数指针。该ID在创建时,被初始化,可以通过pvTimerGetTimerID()函数进行查询。vTimerSetTimerID() and pvTimerGetTimerID()函数直接访问软件定时器,而不是通过命令队列。
使用ID存储软件定时器的 回调函数执行次数的用法举例:
通过xTimerChangePeriod()改变软件定时器的周期,重新计算的过期时间从调用该函数计时开始,而不是从定时器启动开始。如果定时器处于休眠状态,调用xTimerChangePeriod()函数,定时器会计算过期时间,并进入running状态。在中断中调用xTimerChangePeriodFromISR() 函数。
复位软件定时器,使用xTimerReset() API函数,软件定时器的过期时间会从复位时,重新进行计算。如果定时器处于休眠状态,调用该函数,会使定时器重新开始执行。在中断中使用xTimerResetFromISR()函数。
复位软件定时器的应用举例如下:
复位定时器在背光应用场景的举例: