目录
说明:
关于内容:
1)以下内容多为概念了解与步骤分析
2)暂无个人示例代码,使用的是FreeRTOS的官方示例代码
3)若想移植代码测试的,请移步其它地方寻找,下文内容暂无个人示例代码供测试
关于其它:
1)操作系统:win 10
2)平台:keil 5 mdk
3)语言:c语言
4)板子:STM32系列移植FreeRTOS
一、定时器简介
1.1、定时器
从指定是时刻开始,经过一个指定时间,然后触发一个超时事件,用户可以自定义定时器的周期。
1.2、软件定时器
是指具有定时功能的软件,可设置定时周期,当指定时间到达后要调用回调函数(也称为超时函数),用户在回调函数中处理信息。
优点:
1)硬件定时器数量有限,而软件定时器理论上只需要有足够内存,就可以创建多个;
2)使用简单,成本低。
缺点:
1)软件定时器相对硬件定时器来说,精度没那么高(因为它以系统时钟为基准,系统时钟中断优先级又是最低,容易被打断)。对于需要高精度要求的场合,不建议使用软件定时器。
1.3、硬件定时器
芯片本身自带的定时器模块,硬件定时器的精度很高(比软件定时器高),每次在定时时间到达之后就会自动触发一个中断,用户在中断服务函数中处理信息。
1.4、FreeRTOS软件定时器
特点:
1)可裁剪,软件定时器是可裁剪可配置的功能,如果要使能软件定时器,需要将宏定义:configUSE_TIMERT配置项设置为1(不使用设置为0);
2)单次和周期,软件定时器支持设置成:单次定时器或周期定时器。
注意点:
1)软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在改回调函数中使用可能会导致任务阻塞的API函数;
2)软件定时器服务任务:在调用函数vTaskStartScheduler()开启任务调度器的时候,会创建一个管理软件定时器的任务,这个任务称为-->软件定时器服务任务。
1.5、软件定时器服务任务作用
1)负责软件定时器超时的逻辑判断;
2)调用超时软件定时器的超时回调函数;
3)处理软件定时器命令队列。
1.6、软件定时器的命令队列
FreeRTOS提供了许多软件定时器相关的API函数,这些API函数大多都是往定时器的队列中写入消息(本质上是发送命令),这个队列叫做软件定时器命令队列,是提供给FreeRTOS中的软件定时器使用的,用户不能直接访问。
例如:定义了一个任务,开启定时器(API函数往软件定时器命令队列写入消息,发送命令)-->软件定时器命令队列-->软件定时器任务读取软件定时器命令队列消息(接收命令)。
1.7、软件定时器相关配置
1)如果要使能软件定时器,需要将宏定义:configUSE_TIMERT配置项设置为1(不使用设置为0),在启动任务调度器时,会自动创建软件定时器的服务/守护任务prvTimerTask();
2)软件定时器服务任务的优先级为configTIMER_TASK_PRIORITY=31(最大任务优先级);
3)定时器的命令队列长度为configTIMER_QUEUE_LENGTH=5。
注意点:
1)软件定时器的超时回调函数是在软件定时器服务任务中被调用的,服务任务不是专为某个定时器服务的,它还要处理其他定时器,所以定时器的回调函数-->不要影响其他定时器任务,即不能调用那些会阻塞任务的API函数,如:vTaskDelay();
2)访问队列或信号量的非零阻塞时间的API函数也不能调用。
软件定时器的状态:
1)休眠态:软件定时器可以通过其句柄被引用,但因为没有运行,所以其定时超时回调函数不会被执行;
2)运行态:运行态的定时器,当指定时间到达之后,它的超时回调函数会被调用。
注意:新创建的软件定时器处于休眠态,也就是未运行
那么如何让软件定时器从休眠态转变为运行态?
发送命令队列!
1.8、单次定时器和周期定时器
1)单次定时器:单次定时器一旦定时超时,之后执行一次其软件定时器超时回调函数,不会自动重新开启定时,不过可以被手动重新开启;
2)周期定时器:周期定时器的一旦启动以后就会在执行完回调函数以后自动的重新启动,从而周期地执行其软件定时器回调函数。
1.9、软件定时器结构体
结构体成员:
typedef struct tmrTimerControl
{
const char * pcTimerName;
ListItem_t xTimerListItem;
TickType_t xTimerPeriodInTicks;
void * pvTimerID;
TimerCallbackFunction_t pxCallbackFunction;
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTimerNumber;
#endif
uint8_t ucStatus;
} xTIMER;
含义:
名称,pcTimerName,含义:软件定时器名字
名称,xTimerListItem,含义:然后定时器列表项
名称,xTimerPeriodInTicks,含义:软件定时器周期
名称,pvTimerID,含义:软件定时器ID-->区分不同定时器
名称,pxCallbackFunction,含义:软件定时器回调函数
名称,uxTimerNumber,含义:软件定时器编号,调试用
名称,ucStatus,含义:软件定时器的状态
二、软件定时器相关API函数
2.1、创建软件定时器函数
动态创建函数实现:
TimerHandle_t xTimerCreate( const char * const pcTimerName,
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload,
void * const pvTimerID,
TimerCallbackFunction_t pxCallbackFunction );
参数含义:
名称,pcTimerName,含义:软件定时器名
名称,xTimerPeriodInTicks,含义:定时超时时间,单位是:系统时钟节拍
名称,uxAutoReload,含义:定时器模式,pdTRUE:周期定时器,pdFALSE:单次定时器
名称,pvTimerID,含义:软件定时器ID,用于多个软件定时器公用一个回调函数时区分
名称,pxCallbackFunction ,含义:软件定时器超时回调函数
返回值含义:
返回,NULL,含义:软件定时器创建失败
返回,其他值,含义:软件定时器创建成功,返回句柄
2.2、开启软件定时器函数
代码实现:
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
参数含义:
名称,xTimer,含义:待开启的软件定时器的句柄
名称,xTicksToWait ,含义:发送命令到软件定时器命令队列的最大等待时间
返回值含义:
返回,pdPASS,含义:软件定时器开启成功
返回,pdFAIL,含义:软件定时器开启失败
2.3、停止软件定时器函数
代码实现:
BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
参数含义:
名称,xTimer,含义:待停止的软件定时器的句柄
名称,xTicksToWait ,含义:发送命令到软件定时器命令队列的最大等待时间
返回值含义:
返回,pdPASS,含义:软件定时器停止成功
返回,pdFAIL,含义:软件定时器停止失败
2.4、复位软件定时器函数
代码实现:
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
参数含义:
名称,xTimer,含义:待复位的软件定时器句柄
名称,xTicksToWait ,含义:发送命令到软件定时器命令队列的最大等待时间
返回值含义:
返回,pdPASS,含义:软件定时器复位成功
返回,pdFAIL,含义:软件定时器复位失败
说明:
该功能将使软件定时器的重新开启定时,复位后软件定时器重新从0个时间单位开始计数。
2.5、更改软件定时器超时时间函数
代码实现:
BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
TickType_t xNewPeriod,
TickType_t xTicksToWait );
参数含义:
名称,xTimer,含义:待更新的软件定时器句柄
名称,xNewPeriod,含义:新的定时超时时间,单位:系统时钟节拍
名称,xTicksToWait ,含义:发送命令到软件定时器命令队列的最大等待时间
返回值含义:
返回,pdPASS,含义:软件定时器定时超时时间修改成功
返回,pdFAIL,含义:软件定时器定时超时时间修改失败
2.6、删除软件定时器函数
代码实现:
BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );
参数含义:
名称,xTimer,含义:待删除的软件定时器句柄
名称,xTicksToWait ,含义:发送命令到软件定时器命令队列的最大等待时间