FreeRTOS中加入了软件定时器这个功能组件,是一个可选的不属于freeRTOS内核的功能,由定时器服务任务(其实就是一个定时器任务)来提供。

软件定时器是当设定一个定时时间,当达到设定的时间之后就会执行指定的功能函数,而这个功能函数就叫做回调函数。也就是说回调函数的两次执行间隔叫做定时器的定时周期。

回调函数:回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。警告:不能在回调函数中调用任何会阻塞任务的API函数 !比如,定时器回调函数中不能调佣vTaskDelay()、vTaskDelayUnti(),还有一些访问队列或者信号量的非零阻塞时间的API函数。

总之,软件定时器主要是用于定时触发或者是周期性执行的触发功能,从很多特种描述看,感觉是用软件模拟了一个定时中断ISR。软件定时器由Free RTOS内核实现并控制。 它们不需要硬件支持,也与硬件定时器或硬件计数器无关。

说明:我使用的FreeRTOS版本为(FreeRTOS Kernel V10.4.3 LTS Patch 2)

一、FreeRTOS启用软件定时器

FreeRTOS软件定时器是一个可选的不属于freeRTOS内核的功能,因此要在FreeRTOS中使用软件定时器的话,需要在配置文件freeRTOSConfig.h中添加如下所示的4个宏:

#define configUSE_TIMERS             1       //使能软件定时器
#define configTIMER_TASK_PRIORITY       7       //软件定时器的优先级
#define configTIMER_QUEUE_LENGTH        10      //软件定时器的队列长度
#define configTIMER_TASK_STACK_DEPTH    (configMINIMAL_STACK_SIZE * 5)      //软件定时器的堆栈空间大小(单位是字)

二、FreeRTOS软件定时器的种类

FreeRTOS定时器有两种:单次定时器和周期定时器。

1、单次定时器

单次定时器定时时间到了,只执行一次回调函数,之后不会再执行。只有再次重新启动它,才会再执行一次。也就是说,定时器启动一次,开始计时,时间到了,执行一次回调函数。要想再次执行,必须重新启动它。

2、周期定时器

周期定时器根据设定的时间周期的执行的。它一旦启动以后,每执行一次完一次回调函数以后定时器会自动重启,回调函数会周期性的执行。周期定时器相当于单片机硬件定时器中配置为自动重装定时器。

单次定时器和周期定时器的示意图如下所示:

三、FreeRTOS软件定时器API函数

FreeRTOS软件定时器API函数包含:1、创建软件定时器。2、启动软件定时器。3、停止定时器。4、复位定时器。5、查询定时器是否已经开始运行。

1、创建软件定时器

TimerHandle_t xTimerCreate( const char * const pcTimerName,  /* 定时器名字 */const TickType_t xTimerPeriodInTicks,  /* 定时器周期 */const UBaseType_t uxAutoReload,  /* 单次定时器或者周期定时器式 */void * const pvTimerID,          /* 定时器 ID */   TimerCallbackFunction_t pxCallbackFunction )/* 定时器回调函数 */

API函数 xTimerCreate 用于创建软件定时器。

(1)、pcTimerName:定时器名字,一般用于调试,方便识别不同的定时器。

(2)、xTimerPeriodInTicks:定时器周期,单位是系统时钟节拍。

(3)、uxAutoReload:选择定时器是周期模式还是单次模式。若参数为 pdTRUE,则表示选择周期定时器,若参数为pdFALSE,则表示选择单次定时器。

(4)、pvTimerID:定时器的 ID。当创建多个不同的定时器,但又使用同一个回调函数时,在回调函数中就可以通过不同的ID 号来区分不同的定时器。

(5)、pxCallbackFunction:定时器的回调函数。

返回值:创建成功返回定时器的句柄,失败会返回 NULL。

例子:创建一个单次触发的软件定时器示例如下:

软件定时器的名字为singalTIMERS,定时器的ID号=1,定时周期=500毫秒。

    /*创建单次定时器*/xTimers = xTimerCreate("singalTIMERS",     //软件定时器的名字  500,                //定时器周期(500毫秒),单位时钟节拍pdFALSE,   //定时器模式,pdTRUE为周期定时器,pdFALSE为单次定时器(void*)1,           //定时器的ID号=1vTimerCallback);    //定时器回调函数

2、启动软件定时器

启动软件定时器分为两种:1、在任务中启动定时器。2、在中断中启动定时器。

2.1、在任务中启动定时器

BaseType_t xTimerStart( TimerHandle_t xTimer,        /* 定时器句柄 */TickType_t xBlockTime ); /* 成功启动定时器前的最大等待时间设置,单位系统时钟节拍 */

API函数 xTimerStart 用于启动软件定时器。

(1)、xTimer:定时器句柄。

(2)、xBlockTime:成功启动定时器前的最大等待时间设置,单位系统时钟节拍。
返回值:返回 pdFAIL 表示此函数向消息队列发送消息失败,返回 pdPASS 表示此函数向消息队列发送消息成功。

注意:定时器组的大部分API函数不是调用后就会直接运行的,而是通过消息队列给定时器任务发消息来实现的,此参数设置的等待时间就是当消息队列已经满的情况下,等待消息队列有空间时的最大等待时间。
        注意:定时器任务实际执行消息队列发来的命令依赖于定时器任务的优先级,如果定时器任务是高优先级会及时得到执行,如果是低优先级,就要等待其余高优先级任务释放 CPU 权才可以得到执行。

例子:在任务中启动软件定时器示例如下:

xTimerStart(xTimers, 200);

表示刚刚创建的单次周期定时器,定时周期=500毫秒,等待消息队列有空间时的最大等待时间为200毫秒。

2.2、在中断中启动定时器

BaseType_t   xTimerStartFromISR(TimerHandle_t  xTimerBaseType_t*    pxHigherPriorityTaskWoken);

(1)、XTimer:软件定时器的句柄
(2)、pxHigherPriorityTaskWoken:退出此函数时是否要进行任务切换

返回值:
pdPASS:软件定时器开启成功。
pdFAIL:软件定时器开启失败。

例子:在中断中启动软件定时器示例如下:

void USART2_IRQHandler(void)
{BaseType_t xHigherPriorityTaskWoken = pdFALSE;    //不进行任务切换if (xTimerStartFromISR(xTimers , &xHigherPriorityTaskWoken) != pdPASS){//软件定时器开启失败}
} 

3、停止定时器

停止软件定时器分为两种:1、在任务中停止定时器。2、在中断中停止定时器。

3.1、在任务中停止定时器

BaseType_t xTimerStop(TimerHandle_t xTime,TickType_t xTicksToWait)

(1)、xTimer:软件定时器的句柄。
(2)、xTicksToWait:阻塞时间,即停止定时器最大的等待时间。

返回值:
pdPASS:软件定时器停止成功
pdFAIL:软件定时器停止失败

例子:停止软件定时器示例如下:

xTimerStop(xTimers, portMAX_DELAY);

3.2、在中断中停止软件定时器

xTimerStopFormISR(TimerHandle_t xTimer,BaseType_t pxHigherPriorityTaskWoken);

(1)、xTimer:软件定时器句柄
(2)、pxHigherPriorityTaskWoken:退出此函数时是否要进行任务切换

返回值:
pdPASS:软件定时器停止成功。
pdFAIL:软件定时器停止失败。

4、复位定时器

复位软件定时器分为两种:1、在任务中复位定时器。2、在中断中复位定时器。

警告:复位软件定时器,会重新计算定时周期到达的时间点,这个新的时间点是相对于复位定时器的那个时刻计算的,并不是第一次启动软件定时器的那个时间点!!!

假设:定时周期=5秒,调用xTimerStart后,定时器已经运行了3秒,此时调用xTimerReset复位定时器,定时器会从当前时刻(3秒)时刻,重新启动,当5秒后,执行一次回调函数。

4.1、在任务中复位定时器

BaseType_t xTimerReset(TimerHandle_t  xTimer,TickType_t xTicksToWait)

(1)、xTimer:软件定时器的句柄。
(2)、xTicksToWait:阻塞时间,即停止定时器最大的等待时间。

返回值:
pdPASS:软件定时器复位成功
pdFAIL:软件定时器复位失败

4.2、在中断中复位定时器

BaseType_t xTimerResetFromISR(TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken);

(1)、xTimer:软件定时器句柄
(2)、pxHigherPriorityTaskWoken:退出此函数时是否要进行任务切换

返回值:
pdPASS:软件定时器复位成功。
pdFAIL:软件定时器复位失败。

5、查询定时器是否已经开始运行

BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )

查询定时器以查看它是活动的还是休眠的。如果出现以下情况,计时器将处于休眠状态:

  1. 已创建但未启动。
  2. 已过期的计时器尚未重新启动。

返回值:
pdFALSE,没有运行。其他值,运行。

四、实例

下面我们创建一个单次周期软件定时器,定时器的名字为singalTIMERS,定时器的ID号=1,定时周期=500毫秒。

1、配置文件freeRTOSConfig.h中添加如下所示的4个宏:

#define configUSE_TIMERS             1       //使能软件定时器
#define configTIMER_TASK_PRIORITY       7       //软件定时器的优先级
#define configTIMER_QUEUE_LENGTH        10      //软件定时器的队列长度
#define configTIMER_TASK_STACK_DEPTH    (configMINIMAL_STACK_SIZE * 5)      //软件定时器的堆栈空间大小(单位是字)

注意:软件定时器的优先级为7,那么configMAX_PRIORITIES的优先级至少为8,我设置的configMAX_PRIORITIES优先级为8,参见下图

2、包含头文件

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "timers.h"

3、定义定时器句柄

TimerHandle_t xTimers = NULL;               //单次定时器

4、定义回调函数

static void vTimerCallback(xTimerHandle pxTimer);    //单次定时器回调函数/*
**************************************************************************************
*   函 数 名: vTimerCallback
*   功能说明: 定时器回调函数
*   形    参: 无
*   返 回 值: 无
**************************************************************************************
*/
static void vTimerCallback(xTimerHandle pxTimer)
{configASSERT(pxTimer);//添加用户代码
}

5、动态创建定时器

    /*创建单次定时器*/xTimers = xTimerCreate("singalTIMERS",     //软件定时器的名字  200,        //定时器周期,单位时钟节拍pdFALSE,    //定时器模式,pdTRUE为周期定时器,pdFALSE为单次定时器(void*)1,         //定时器的ID号vTimerCallback);   //定时器回调函数

想要搞清楚【FreeRTOS 的软件定时器消息队列】的内核知识,请参阅以下文章:

(10条消息) FreeRTOS个人笔记-软件定时器_Couvrir洪荒猛兽的博客-CSDN博客_freertos 定时器

FreeRTOS 软件定时器的使用相关推荐

  1. FreeRTOS 软件定时器使用

    FreeRTOS 的软件定时器工作模式有两种:单次触发 和 自动重载. 1. 主要功能函数介绍 官方API文档:FreeRTOS 软件定时器 API文档 最为常用的函数有: // 创建软件定时器,返回 ...

  2. FreeRTOS软件定时器 | FreeRTOS十三

    目录 说明: 一.定时器简介 1.1.定时器 1.2.软件定时器 1.3.硬件定时器 1.4.FreeRTOS软件定时器 1.5.软件定时器服务任务作用 1.6.软件定时器的命令队列 1.7.软件定时 ...

  3. freeRTOS — 软件定时器的使用

    freeRTOS中加入了软件定时器这个功能组件,是一个可选的.不属于freeRTOS内核的功能,由定时器服务(其实就是一个定时器任务)来提供. 软件定时器是当设定一个定时时间,当达到设定的时间之后就会 ...

  4. FreeRTOS软件定时器 基于STM32

    文章目录 一·.软件定时器的基本概念 二.软件定时器应用场景 三.软件定时器的精度 四.软件定时器的运作机制 五.软件定时器函数接口讲解 1.软件定时器创建函数 xTimerCreate() 2.软件 ...

  5. FreeRtos软件定时器复习

    一.基础概念 概念解析:定时器分为硬与软定,硬件定时器到达定时时间自动触发中断服务函数,使用软件定时器时,需要我们在创建软件定时器时指定时间到达后要调用的函数(也称超时函数/回调函数,为了统一,下文均 ...

  6. STM32cubeMX配置FreeRTOS软件定时器

    文章目录 前言 1.软件定时器概述 一.软件定时器特性 二.使用cubeMX生成软件定时器 三.代码讲解 总结 前言 本文主要带大家了解什么是软件定时器,并且带大家使用cubeMX配置软件定时器. 1 ...

  7. FreeRTOS 软件定时器

    系统节拍配置宏 configTICK_RATE_HZ, 即1S能跳动多少下, 软件定时器的运作机制. FreeRTOS 采用两个定时器列表维护软件定时器, pxCurrentTimerList 与 p ...

  8. freeRtos学习笔记 (6)软件定时器

    freeRtos学习笔记 freeRtos软件定时器 软件定时器需要注意事项 软件定时器的精度基于时钟节拍,例如系统时钟节拍为10ms, 软件定时器定时时间必须是10ms的整数倍,因此软件定时器一般用 ...

  9. FreeRTOS源码分析与应用开发06:软件定时器

    目录 1. 概述 1.1 软件定时器 & 硬件定时器 1.2 软件定时器精度 1.3 单次模式 & 周期模式 2. 软件定时器组件 2.1 定时器任务 2.2 定时器列表 2.3 定时 ...

最新文章

  1. 骚操作!阿里对业务中台痛下杀手!但却继续推进数据中台?
  2. java新建测试程序_java – 如何创建一个CloseableHttpResponse对象来帮助测试?
  3. 学习oop知识之OOP的封装
  4. 中国电信:全业务IP网络的安全运营
  5. 提高python执行效率_提升Python程序运行效率的6个方法
  6. Android控件第6类——杂项控件
  7. python处理大数据越来越慢_请问使用JdbcTemplate读取大数据很慢如何优化?(十几万数据)...
  8. ubuntu各版本的区别
  9. linux内存管理:kmap、vmap、ioremap
  10. html渐变显示动画效果,使用CSS transition和animation改变渐变状态
  11. LINUX SHELL中数组的使用
  12. 激活函数maxout
  13. python微博评论情感分析_用python对鹿晗、关晓彤微博进行情感分析
  14. 苹果截屏快捷键_Mac进阶:掌握这 5 个冷门快捷键,让Mac更好用
  15. 世界上云平台有很多,但叫机智云的只有一个。
  16. Python程序不使用函数将字符大写
  17. 单选按钮RadioButton使用
  18. 微信小程序人员组织结构
  19. ironpython教程_用IronPython写winform程序-.NET教程,Asp.Net开发
  20. 外商独资企业必须有监事吗

热门文章

  1. 对div实现右键弹出自定义菜单
  2. 汇编知识点——符号与段定义的伪指令EQU,ASSUME,END
  3. php较短加密算法,php - 寻求一种可逆加密算法,加密数据库自增主键,要求密文越短越好。...
  4. 夜深人静做游戏---之一
  5. GitHub 增加贡献者 统计贡献
  6. [转载]SteamVR脚本解析
  7. 创业这么“难”?还没开始就被劝退?
  8. 《小王子》80 周年:安东尼‧圣修伯里的笔下著名主人公进入元宇宙
  9. VMWare 15.5.7 虚拟机配置,实现互联网访问和本地访问虚拟机
  10. 中电金信:数字化转型|银行业数据中心数字化转型之驱动篇