5 FreeRTOS软件定时器
-
5.1 软件定时器的简介
定时器是每一个MCU具备的基本外设,高级MCU其定时器功能强大,能提供PWM、输入捕获等功能。MCU自带的定时器属于硬件定时器,不同的MCU其硬件定时器的数量各不同。在FreeRTOS中也提供定时器功能,该类定时器是软件定时器,其精度没有硬件定时器的高,但还是能够处理要求不高的任务。
软件定时器允许设置一段时间,当设置的时间达到预设值之后将会执行所指定的功能函数,此功能函数叫做定时器的回调函数。该回调函数的两次执行的间隔叫做定时器的定时周期。
【使用注意事项】
软件定时器的回调函数是在定时器服务任务重执行的,因此一定不能在该回调函数中使用会阻塞任务的API函数!如:vTaskDelay( )、vTaskDelayUnti( ),还有那些访问队列、信号量的非零阻塞时间的API函数。 -
5.2 软件定时器的配置
A. configUSE_TIMERS
如果需要使用软件定时器的话,该宏一定要设置为1,此时定时器服务任务就会在启动FreeRTOS调度器的时候自动创建;
B. configTIMER_TASK_PRIORITY
设置软件定时器服务任务的任务优先级,可设置为0~(configMAX_PRIORITIES-1),优先级的设置需根据实际的应用所需进行设置,优先级越高,定时器命令队列中的命令和定时器回调函数就会及时得到处理;
C. configTIMER_QUEUE_LENGTH
此处用于设置定时器命令队列的队列长度;
D. configTIMER_TASK_STACK_DEPTH
此宏用来设置定时器服务任务的任务堆栈大小,单位为字,不是字节哟!!!对于STM32来说,一个字就是4字节。由于定时器服务任务中会执行定时器的回调函数,因此任务堆栈的大小一定要根据定时器的回调函数来设置。 -
5.3 单次定时器和周期定时器
软件定时器可被分为两种:单次定时器和周期定时器。
单次定时器的定时器回调函数就只执行一次,如:定时1s,当定时的时间到了,就会执行一次定时器回调函数,之后定时器就会停止运行了;我们可以再次手动启动该定时器,但是单次定时器不能自动重启;
周期定时器在启动之后会在执行完该回调函数后再自动重新启动,因此回调函数就会周期性的执行。 -
5.4 创建软件定时器
函数 xTimerCreate( ) TimerHandle_t xTimerCreate( const char * const pcTimerName, TickType_t xTimerPeriodInTicks, UBaseType_t uxAutoReload, void * pvTimerID, TimerCallbackFunction_t pxCallbackFunction); 参数: pcTimerName:软件定时器的名字,为字符串; xTimerPeriodInTicks:软件定时器的定时周期; uxAutoReload:设置定时器的模式,单次定时器还是周期定时器; pvTimerID:定时器ID,FreeRTOS支持多个定时器共用同一个回调函数,在回调函数中可根据此ID来处理不同的定时器; pxCallbackFunction:定时器回调函数。 函数xTimerCreateStatic( ) TimerHandler_t xTimerCreateStatic( const char* const pcTimerName, TickType_t xTimerPeriodInTicks, UBaseType_t uxAutoReload, Void * pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer ); pxTimerBuffer:指向StaticTimer_t类型的变量,用于保存定时器结构体 返回值: NULL:软件定时器创建失败; 其他值:创建成功的软件定时器的句柄。
-
5.5 复位软件定时器
在定时器正在运行的时候需要复位软件定时器,复位软件定时器的话会重新计算定时周期到达的时间点,该新的时间点是相对于复位定时器的那个时刻计算的,并不是第一次启动软件定时器的那个时间点。演示过程如下:
函数xTimerReset BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTickToWait); 参数: xTimer:要复位软件定时器的句柄; xTickToWait:设置阻塞的时间,调用该函数复位软件定时器,其实是向定时器命令队列中发送一条tmrCOMMAND_RESET命令,因此涉及到队列的操作,就会涉及到队列的阻塞时间设置。 返回值: pdPASS:软件定时器复位成功,说白了就是复位命令发送成功; pdFAIL:软件定时器复位失败,命令发送失败。 函数xTimerResetFromISR( ) BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken );
-
5.6 开启关键定时器
函数 xTimerStart() BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); 函数 xTimerStartFromISR() BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, BaseType_t * pxHigherPriorityTaskWoken );
-
5.7 停止软件定时器
函数 xTimerStop( ) BaseType_t xTimerStop ( TimerHandle_t xTimer, TickType_t xTicksToWait ); 函数 xTimerStopFromISR( ) BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, BaseType_t * pxHigherPriorityTaskWoken );