FreeRTOS-软件定时器

以下内容为个人的初学记录,如有错误,欢迎指正。

概述

顾名思义,软件定时器就是用来定时,到了设定的时间(周期)时会执行一些事情(回调函数)。

包括:自动装载定时器(周期性)、一次性定时器

类似于闹钟,有周期性闹钟和一次性闹钟,周期性闹钟不需要你每天都去设置,但是一次性闹钟在完成一次后就会关闭,需要你手动设置开启;

软件定时器相关的函数,比如xTimerStart()等,虽然是可以在普通的任务中调用,但并没有直接操作定时器,而是把命令发送到定时器命令队列,由DaemonTask(守护任务)读取并对执行和操作相关命令。也就是说,软件定时器是在DaemonTask中被操作的,包括创建、开启等。

DaemonTask优先级为:configTIMER_TASK_PRIORITY;
定时器命令队列的长度:为configTIMER_QUEUE_LENGTH;

当configUSE_TIMERS被设置为1时,在启动调度器时,会自动创建RTOS Damemon Task的任务。它内部可以包含对多个定时器的操作函数。当【命令队列有任务】、【某个定时器超时】时,阻塞的DaemonTask会退出阻塞进入就绪态;

软件定时器工作流程:

  1. DaemonTask创建定时器,定时器进入冬眠状态(dormant);
  2. DaemonTask开启定时器,定时器进入运行状态 ;[下图的三个函数(start启动、reset复位、changeperiod修改周期)都能实现开启];
  3. 如果是【自动装载】,则一直运行,到了定时时间就处理回调函数 1 ;当使用stop函数时进入冬眠;
  4. 如果时【一次性】,则超时一次,执行回调函数后就进入冬眠;

特别注意,在外部任务调用xTimerStart()不一定能使定时器运行,必须是DaemonTask执行了开启的操作才行。
假设有任务Task和DaemonTask,DaemonTask优先级较低,且处于阻塞。当任务Task调用xTimerStart()发出【开启定时器】的命令时,命令队列有数据使得DaemonTask进入就绪态。但是由于优先级原因,DaemonTask无法开启定时器。

软件定时器工作流程示意图

图片来源:百问网FreeRTOS:第16章 软件定时器(software timer)

函数

创建

首先是动态创建:

TimerHandle_t xTimerCreate( const char * const pcTimerName,  
       			const TickType_t xTimerPeriodInTicks, 
       			const UBaseType_t uxAutoReload, 
       			void * const pvTimerID, 
       			TimerCallbackFunction_t pxCallbackFunction );

返回值:句柄/NULL
pcTimerName:定时器名字
xTimerPeriodInTicks:周期(单位:Tick)
uxAutoReload:pdTRUE-自动装载 / pdFALSE-一次性
pvTimerID:给回调函数使用,用于区分哪个定时器;
pxCallbackFunction:回调函数

静态创建:

TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, 
                                 TickType_t xTimerPeriodInTicks, 
                                 UBaseType_t uxAutoReload, 
                                 void * pvTimerID, 
                                 TimerCallbackFunction_t pxCallbackFunction, 
                                 StaticTimer_t *pxTimerBuffer );

删除

BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); 

由于要向定时器命令队列发送命令,有可能会出现满队列的情况,因此需要xTicksToWait

启动、停止

/*启动*/
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
BaseType_t xTimerStartFromISR(TimerHandle_t xTimer, 
                              BaseType_t *pxHigherPriorityTaskWoken); 

/*停止*/
BaseType_t xTimerStop(TimerHandle_t xTimer, TickType_t xTicksToWait);
BaseType_t xTimerStopFromISR(TimerHandle_t xTimer, 
                             BaseType_t *pxHigherPriorityTaskWoken); 

复位

BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); 

修改周期

BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, 
                               BaseType_t *pxHigherPriorityTaskWoken );

参考:百问网FreeRTOS:第16章 软件定时器(software timer)


  1. 从定时器被开启到第一次超时,中间的时间应该从开启函数被外部任务调用时开始; ↩︎

  • 25
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值