FreeRTOS 软件定时器的使用

2023-11-01

        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号=1
                            vTimerCallback); 	//定时器回调函数
								  

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  xTimer
    		                   BaseType_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 定时器

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS 软件定时器的使用 的相关文章

  • FreeRTOS快速上手

    FreeRTOS使用 一 源码下载和移植文件提取 1 1 源码下载 在网站https sourceforge net projects freertos 可以找到freertos最新的源码 1 2 移植文件提取 根据第一步 我们会得到一个f
  • FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列 但是在FreeRTOS中任务间的通讯还有信号量 邮箱 事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 增加邮箱部分 任务通知发送消息 Demo 202
  • APP移动应用测试策略与工具思维导图

    2张图构建移动应用测试知识体系 1 APP移动测试策略 2 移动测试常用工具 目前觉得好用的 因还有其它事 故这里不再啰嗦 想要听我啰嗦的 改天书里见
  • freeRTOS手册 第六章 . 中断管理

    如果我对本翻译内容享有所有权 允许任何人复制使用本文章 不会收取任何费用 如有平台向你收取费用与本人无任何关系 第六章 中断管理 章节介绍和范围 事件 嵌入式实时系统必需对环境中的事件做出响应 比如 外部网络设备收到一个发送给TCP IP栈
  • FreeRTOS+CubeMX系列第一篇——初识FreeRTOS

    文章目录 一 关于FreeRTOS 二 FreeRTOS的特点 三 如何在CubeMX上配置FreeRTOS 四 FreeRTOS文档资料 五 同系列博客 一 关于FreeRTOS 1 什么是FreeRTOS FreeRTOS是一个迷你的实
  • FreeRTOS临界区

    FreeRTOS临界区是指那些必须完整运行 不能被打断的代码段 比如有的外设的初始化需要严格的时序 初始化过程中不能被打断 FreeRTOS 在进入临界区代码的时候需要关闭中断 当处理完临界区代码以后再打开中断 FreeRTOS 系统本身就
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • 【FreeRTOS】任务通知的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • FreeRTOS学习---“定时器”篇

    总目录 FreeRTOS学习 任务 篇 FreeRTOS学习 消息队列 篇 FreeRTOS学习 信号量 篇 FreeRTOS学习 事件组 篇 FreeRTOS学习 定时器 篇 FreeRTOS提供了一种软件定时器 用来快速实现一些周期性的
  • freeRTOS出现任务卡死的情况。

    最近在做一个产品二代升级的项目 代码是上一任工程师留下的 很多BUG 而且融合了HAL库和LL库 以及github上下载的GSM源码 很不好用 我这边是将2G模块换成了4G 且添加了单独的BLE模块 因此只在源码的基础上 去除2G和BLE代
  • STM32 Freertos 添加 外部sram heap_5.c

    1 添加外部SRAM 初始化 2 添加heap 5 c 3 初始化heap 5 c 外部堆栈 Define the start address and size of the two RAM regions not used by the
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • 有可用的 FreeRTOS 解释语言库吗?

    我在一家公司工作 该公司使用 FreeRTOS 为多个设备创建固件 最近 我们对新功能的要求已经超出了我们固件工程师的工作能力 但我们现在也无力雇用任何新人 即使进行微小的更改 也需要固件人员在非常低的级别上进行修改 我一直在为 FreeR
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d

随机推荐

  • httpclient请求403

    问题 httpclient请求对方服务器报403 用postman是可以的 原因 HttpPost request new HttpPost uri request setHeader User Agent Mozilla 5 0 Wind
  • Android开发

    1 Android简介 Android一词的本义指 机器人 同时也是Google于2007年11月5日宣布的基子 Linx平台的开源手机操作系统的名称 该平台由操作系统 中间件 用户界面和应用软组成 Android系统具有如下5个特点 开放
  • CSS深入剖析border和box-shadow(附漂亮样式)

    剖析border 一 border radius 二 border image 三 box shadow 四 利用这些属性渲染出漂亮图形 在CSS3中赋予了border更过的功能 但是其知识结构也更加复杂 在本文中博主对border进行深入
  • 线性空间与线性变换

    1 1线性空间 广义的概念 如何证明一个向量集合是线性空间 1 首先问下什么是线性空间 2 如何表示该集合中的全部向量 知识点1 首先我们需要知道什么是空间 空间其实就是向量的集合 而什么是线性空间呢 定义了线性运算的非空集合 线性运算指的
  • Photoshop出现无法完成,因为内存不够(RAM),如何解决?

    Photoshop出现无法完成 因为内存不够 RAM 时 你所需要如下步骤进行系统的适用 1 在你点击 编辑 首选项 性能 系统提示中如果出现了 要求在96和8之间的整数 已插入最接近的数 这个就需要你在注册表中进行操作 操作如下 1 wi
  • 加拿大安省欢ajax,加拿大安省省考OSSLT介绍

    原标题 加拿大安省省考OSSLT介绍 加拿大省考相当于中国的会考 必须通过才可以取得加拿大高中毕业证 不同省份的省考 BC省除外 目前已取消省考 对申请大学的影响不同 安大略省的省考只有一门课 即由安大略省教育质量和问责办公室 EQAO 举
  • Sqoop简介、原理、安装、简单使用案例、一些常用命令及参数

    问题导读1 Sqoop原理是怎样的 2 如何利用Sqoop导入数据 3 如何利用Sqoop导出数据 4 Sqoop常用的命令及对应参数有哪些 第1章 Sqoop 简介 Sqoop 是一款开源的工具 主要用于在 Hadoop Hive 与传统
  • vector 的作用

    c 中 vector作为容器 它的作用是 一个动态数组模板类 你可以把它当做一个普通数组用 但是他的功能远比一般数组强大 数组最大的不好就是数组长度的限制和删除其中一个时候的后续移位问题 这些在vector中都得到了完美的解决 而且可以存储
  • 教你一步步创建属于自己的Python爬虫代理IP池(含代码示例)

    前言 在进行网络数据采集时 遇到反爬虫限制是常见的问题 使用代理IP可以帮助我们绕过这些限制 保护自己的爬虫程序 本文将教您如何使用Python创建属于自己的代理IP池 以便获取可用的代理IP并应用于 Python爬虫程序 同时 我们将提供
  • 关于Qt调用多/两次setupUi导致信号与槽自动连接失败问题

    代码场景 函数内部调用两次 setupUi okBtn自动连接槽函数失效 问题分析 在 setupUi 函数内部调用了这么一个函数 connectSlotsByName 从函数名来看就是通过名字 部件名 连接信号与槽 官方文档的解释 所以流
  • Spring@Autowired注解与自动装配

    今天在预发布环境配置一个manager的时候 应用启动失败 报错 Caused by org springframework beans factory BeanCreationException Could not autowire fi
  • ELK日志采集平台(四)---轻量级采集工具metricbeat

    目录 一 安装metricbeat 二 与kibana数据可视化联用 logstash是负责采集数据的 是入口 流向为logstash gt ES gt kibana 但是它的资源消耗很大 有时候没那么多内存给他占用 同时有些定制的采集指标
  • 使用freemaker 导出word 包含分页,表格循环java

    在平时项 目开发中 相信或多或少的都遇到过word导出的需求 这里整理一个比较全面的java word导出方法 希望可以跟大家一起交流学习 创建word模板 1 1 新建一个word模板 并修改字段 2 将word文件另存为xml 格式 打
  • 进程 第三天 (线程&线程间通信)

    印象笔记 进程 第三天 线程 线程间通信 一 线程简介 1 线程的基本概念 通过之前的学习我们知道 进程是系统中资源执行和资源分配的最小单位 每个进程都有自己独立的数据区 代码区 堆栈区等 这就造成了当进程切换时 操作系统需要额外的操作来清
  • Git使用教程:超详细、超傻瓜、超浅显、真正手把手教

    作者 涂根华 原文链接 https www cnblogs com tugenhua0707 p 4050072 html https mp weixin qq com s M DoeWWSRI P5Et6hm0BIw
  • PowerToys安装

    PowerToys 是微软开发者开发的免费实用工具集 可以用于高级用户调整和简化 Windows 操作 以提高效率 官网安装方法 https learn microsoft com zh cn windows powertoys insta
  • Oracle数据库startup mount时的报错处理(ORA-01078&LRM-00109)

    安装监听 Disconnected oracle rac1 netca Oracle Net Services Configuration oracle rac1 sqlplus as sysdba SQL Plus Release 11
  • 在win10系统下不能运行VC++6.0的解决方法

    win10系统下出现 VC6 0应用程序无法正常启动 0x0000142 解决方法 将英文版的MSDEV exe文件复制粘贴替换到vc 6 0 Microsoft Visual Studio Common MSDev98 Bin文件目录下运
  • 树莓派4B-串口、多串口配置及详细使用攻略

    相比树莓派零 1 2 以及 3 的双串口 UART0 PL011 和 UART1 mini UART 树莓派4 中新增了 4 个 PL011 串口共计有 6 个 UART 整理此笔记用作记录和配置参考 注意 目前搜到的大多数描述树莓派 4
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫