15.1 软件定时器简介
15.1.1 软件定时器概述
软件定时器的功能就是设置一段事件,当设置的事件到达之后就执行指定的功能函数。这个功能函数就叫做回调函数。
15.1.2 编写回调函数的注意事项
软件定时器的回调函数在定时器服务函数任务中执行,所以不能在回调函数中调用任何会阻塞任务的API函数!比如vTaskDelay()、vTaskDelayUnit()、还有一些访问队列或者信号量的非零阻塞时间的API函数。
15.2 定时器服务/Daemon任务
15.2.1 定时器服务任务与队列
定时器是一个可选的功能,且该功能不属于FreeRTOS内核。所以在使用之前要在配置文件中进行配置
定时器功能是由定时器服务(或Daemon)任务来提供的。(Daemon是守护进程,具体的功能及含义还没有搞清楚)
FreeRTOS提供了很多关于定时器的API函数。用户可以调用这些API来使用定时器。但刚才说定时器服务是由定时器服务任务提供的。那么用户在自己的任务中调用定时器服务任务。就相当于两个任务之间进行通讯。所以这些API函数大多数都使用FreeRTOS的队列发送命令给定时器服务任务。这个队列叫做定时器命令队列。
综上,1.软件定时器是FreeRTOS提供的一个可选的功能,在使用之前需要选配。2.用户通过向软件定时器队列中发送命令来使用控制软件定时器。
15.2.2 定时器相关配置
在使用之前需要在FreeRTOSConfig.h中进行配置。有关软件定时器的配置如下:
配置 | 说明 |
---|
configUSE_TIMERS | 使用软件定时器就配置为1,否则为0 |
configTIMER_TASK_PRIORITY | 软件定时器服务任务优先级(0~(configMAX_PRIORITIES-1)) |
configTIMER_QUEUE_LENGTH | 定时器命令队列的队列长度 |
configTIMER_TASK_STACK_DEPTH | 定时器服务任务的任务堆栈大小(单位:字) |
综上,一个使能、一个任务优先级、一个任务堆栈大小、一个队列长度
15.3 单次定时器和周期定时器
单次定时器:运行一次就停止。
周期定时器:运行完一轮后继续开始计时,永不停歇。
综上,周期定时器就相当于对单次定时器加了个重载功能
15.4 复位软件定时器
有时候我们可能会在定时器正在运行的时候需要复位定时器,复位软件定时器的话会重新计算定时周期到达的时间点。通俗点就是将计数值清0,让它重新计数
FreeRTOS提供了两个API函数来完成软件定时器的复位
函数 | 描述 |
---|
xTimerReset() | 在任务中复位软件定时器 |
xTimerResetFromISR() | 在中断函数中复位软件定时器 |
15.4.1 函数 xTimerReset()
该函数的作用就是复位软件定时器,此函数只能用在任务中,不能用在中断服务函数中。另在此函数是一个宏,真正执行的函数是xTimerGenericCommand()。函数原型如下
{tabs-pane label="函数原型"}
BaseType_t xTimerReset(TimerHandle_t xTimer, TickType_t xTicksToWait)
{/tabs-pane}
{tabs-pane label="参数一"}
xTimer: 要复位的软件定时器句柄
{/tabs-pane}
{tabs-pane label="参数二"}
xTicksToWait: 设置的阻塞时间。因为控制定时器复位实际上是向定时器命令队列中发送命令一条tmrCOMMAND_RESET命令。涉及到入队阻塞时间的设置。
{/tabs-pane}
{tabs-pane label="返回值"}
pdPASS:复位成功; pdFAIL:复位失败,及命令发送失败。
{/tabs-pane}
15.4.2 函数 xTimerResetFromISR
此函数是xTimerReset()函数的中断版本,此函数用于中断服务中!此函数是一个宏,真正执行的函数是xTimerGenericCommand(),函数原型如下:
{tabs-pane label="函数原型"}
BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, BaseType_t * pxHigherPriorityTaskWoken );
{/tabs-pane}
{tabs-pane label="参数一"}
xTimer: 要复位的软件定时器句柄
{/tabs-pane}
{tabs-pane label="参数二"}
pxHigherPriorityTaskWoken: 退出此函数后是否需要进行任务切换。及调用portYIELD_FROM_ISR()来完成。
{/tabs-pane}
{tabs-pane label="返回值"}
pdPASS:复位成功; pdFAIL:复位失败,及命令发送失败。
{/tabs-pane}
15.5 创建软件定时器
在使用软件定时器之前要先创建软件定时器
函数 | 描述 |
---|
xTimerCreate() | 动态方法创建软件定时器 |
xTimerCreateStatic() | 静态方法创建软件定时器 |
15.5.1 函数xTimetCreate()
创建一个软件定时器,所需要的内存通过动态内存管理方法分配。新创建的软件定时器处于休眠状态,函数xTimerStart()、xTimerReset()、xTimerStartFromISR()、xTimerResetFromISR()、xTimerChangePeriod()、xTimerChangePeriodFromISR()可以使新创建的定时器进入活动状态,函数原型如下。
{tabs-pane label="函数原型"}
TimerHandle_t xTimerCreate( const char const pcTimerName, TickType_t xTimerPeriodInTicks, UBaseType_t uxAutoReload, void pvTimerID, TimerCallbackFunction_t pxCallbackFunction)
{/tabs-pane}
{tabs-pane label="参数一"}
pcTimerName :软件定时器名字
{/tabs-pane}
{tabs-pane label="参数二"}
xTimerPeriodInTicks :软件定时器的定时器周期,单位是时钟节拍数
{/tabs-pane}
{tabs-pane label="参数三"}
uxAutoReload: 定时器模式(自动重装载使能),单次定时器or周期定时器
{/tabs-pane}
{tabs-pane label="参数四"}
pvTimerID: 定时器ID
{/tabs-pane}
{tabs-pane label="参数五"}
pxCallbackFunction: 定时器回调函数
{/tabs-pane}
{tabs-pane label="返回值"}
NULL: 软件定时器创建失败 其他值: 创建成功的软件定时器句柄
{/tabs-pane}
15.5.2 函数xTimerCreateStatic()
创建一个软件定时器,所需要的内存需要用户自行分配。也需要函数xTimerStart()、xTimerReset()、xTimerStartFromISR()、xTimerResetFromISR()、xTimerChangePeriod()、xTimerChangePeriodFromISR()使新创建的定时器进入活动状态,函数原型如下
{tabs-pane label="函数原型"}
TimerHandle_t xTimerCreateStatic(const char const pcTimerName, TickType_t xTimerPeriodInTicks, UBaseType_t uxAutoReload, void pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t * pxTimerBuffer)
{/tabs-pane}
{tabs-pane label="参数一"}
pcTimerName :软件定时器名字
{/tabs-pane}
{tabs-pane label="参数二"}
xTimerPeriodInTicks :软件定时器的定时器周期,单位是时钟节拍数
{/tabs-pane}
{tabs-pane label="参数三"}
uxAutoReload: 定时器模式(自动重装载使能),单次定时器or周期定时器
{/tabs-pane}
{tabs-pane label="参数四"}
pvTimerID: 定时器ID
{/tabs-pane}
{tabs-pane label="参数五"}
pxCallbackFunction: 定时器回调函数
{/tabs-pane}
{tabs-pane label="参数六"}
pxTimerBuffer: 一个StaticTimer_t类型的变量,用来保存定时器结构体
{/tabs-pane}
{tabs-pane label="返回值"}
NULL: 软件定时器创建失败 其他值: 创建成功的软件定时器句柄
{/tabs-pane}
15.6 开启软件定时器
软件定时器创建完成后或者软件定时器停止运行,可以使用FreeRTOS提供的两个开启函数来启动软件的定时器
函数 | 描述 |
---|
xTimerStart() | 在任务中开启软件定时器 |
xTimerStartFromISR() | 在中断中开启软件定时器 |
15.6.1 函数xTimerStart()
该函数只允许在任务函数中使用 ,不可以在中断函数中调用。如果定时处于就绪状态,未运行,调用该函数会启动定时器。若定时器处于运行状态,调用该函数会重新计算定时器的到期函数,结果和xTimerReset()一样。此函数是个宏,真正执行的是函数 xTimerGenericCommand, 函数原型如下。
{tabs-pane label="函数原型"}
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait)
{/tabs-pane}
{tabs-pane label="参数一"}
xTimer: 要开启的软件定时器的句柄
{/tabs-pane}
{tabs-pane label="参数二"}
xTicksToWait: 向定时器服务任务发送命令的阻塞时间
{/tabs-pane}
{tabs-pane label="返回值"}
pdPASS: 软件定时器开启成功
pdFAIL: 软件定时器开启失败
{/tabs-pane}
15.6.2 函数xTimerStartFromISR()
该函数只允许在中断函数中使用。如果定时处于就绪状态,未运行,调用该函数会启动定时器。若定时器处于运行状态,调用该函数会重新计算定时器的到期函数,结果和xTimerReset()一样。此函数是个宏,真正执行的是函数 xTimerGenericCommand, 函数原型如下。
{tabs-pane label="函数原型"}
BaseType_t xTimerStart( TimerHandle_t xTimer, BaseType_t * pxHigherPriorityTaskWoken)
{/tabs-pane}
{tabs-pane label="参数一"}
xTimer: 要开启的软件定时器的句柄
{/tabs-pane}
{tabs-pane label="参数二"}
pxHigherPriorityTaskWoken: 退出此函数以后是否进行任务切换
{/tabs-pane}
{tabs-pane label="返回值"}
pdPASS: 软件定时器开启成功
pdFAIL: 软件定时器开启失败
{/tabs-pane}
15.7 停止软件定时器
FreeRTOS提供了两个用于停止软件定时器的API函数
函数 | 描述 |
---|
xTimerStop() | 任务中停止软件定时器 |
xTimerStopFromISR() | 中断中停止软件定时器 |
15.7.1 函数xTimerStop()
用于停止一个软件定时器,此函数用于任务中,不可以用在中断服务函数中。此函数是一个宏,真正调用的是函数 xTimerGenericCommand()。函数原型如下:
{tabs-pane label="函数原型"}
BaseType_t xTimerStop ( TimerHandle_t xTimer,TickType_t xTicksToWait )
{/tabs-pane}
{tabs-pane label="参数一"}
xTimer: 要停止的软件定时器的句柄
{/tabs-pane}
{tabs-pane label="参数二"}
xTicksToWait: 向定时器服务任务发送命令的阻塞时间
{/tabs-pane}
{tabs-pane label="返回值"}
pdPASS: 软件定时器停止成功
pdFAIL: 软件定时器停止失败
{/tabs-pane}
15.7.2 函数xTimerStopFromISR()
用于停止一个软件定时器,此函数用于中断函数中,不可以用在任务函数中。此函数是一个宏,真正调用的是函数 xTimerGenericCommand()。函数原型如下:
{tabs-pane label="函数原型"}
BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,BaseType_t * pxHigherPriorityTaskWoken );
{/tabs-pane}
{tabs-pane label="参数一"}
xTimer: 要停止的软件定时器的句柄
{/tabs-pane}
{tabs-pane label="参数二"}
pxHigherPriorityTaskWoken: 退出此函数以后是否进行任务切换
{/tabs-pane}
{tabs-pane label="返回值"}
pdPASS: 软件定时器停止成功
pdFAIL: 软件定时器停止失败
{/tabs-pane}
15.8 软件定时器实验
评论 (0)