FreeRTOS 软件定时器的使用

news/2024/4/29 11:59:44/文章来源:https://blog.csdn.net/ba_wang_mao/article/details/127444714

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_404471.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-switch接口实现

后台返回的数据: active-textswitch 打开时的文字描述string——inactive-textswitch 关闭时的文字描述string——active-valueswitch 打开时的值boolean / string / number—trueinactive-valueswitch 关闭时的值boolean / string / number—falseactive-colorswi…

Enzo丨艾美捷Enzo Ciglitazone解决方案

艾美捷Enzo Ciglitazone是一种噻唑烷二酮类降血糖药。它在遗传性肥胖的C57 Bl/6 ob/ob小鼠中显示抗高血糖活性,并且是选择性PPARγ激动剂(EC50=3M)。抑制人间充质干细胞中HUVEC分化和血管生成,并刺激脂肪生成和减少成骨…

区块链 — Overview

文章目录区块链的概念区块链数据结构区块链的基础技术哈希运算数字签名共识算法智能合约P2P网络区块链分类公有链联盟链私有链区块链的概念 狭义上,区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构,并以密码学方式保证的不…

深度神经网络图像识别,深度神经网络图像配准

如何用Python和深度神经网络寻找相似图像 代码首先,读入TuriCreate软件包import turicreate as tc我们指定图像所在的文件夹image,让TuriCreate读取所有的图像文件,并且存储到data数据框data tc.image_analysis.load_images(./image/)我们来…

《python 可视化之 matplotlib》第一章 折线图 plot

《python 可视化之 matplotlib》第一章 折线图 本章节内容包括以下几方面内容: 绘制曲线 yx2yx^2yx2;让曲线更加光滑;常见的相关属性设置;多条折线图的绘制;折线图之间的颜色填充;时间序列可视化;常见问题…

iNFTnews|在元宇宙中探索NFT的无限可能

元宇宙正在使我们当下的生活发生显著变化。 我们都玩过很多电子游戏,看过很多相关的科幻电影,也有过很多关于元宇宙进入我们日常生活后,我们周围的事物将会受到怎样的巨大影响的讨论。 我们很快就会看到,如此先进的技术突破将逐…

人工神经网络概念及组成,人工神经网络基本概念

1、什么是BP神经网络? BP算法的基本思想是:学习过程由信号正向传播与误差的反向回传两个部分组成;正向传播时,输入样本从输入层传入,经各隐层依次逐层处理,传向输出层,若输出层输出与期望不符&…

含汞废水的深度处理方法

CH-95 是一款为了从工业废水中去除回收汞和贵金属而专门开发的螯合树脂。拥有聚乙烯 异硫脲官能基的大孔树脂,这种树脂对汞有极高的选择性。钠,碱土,铁铜等重金属等不能干扰 其对汞的选择性去除。 CH-97 是一款含有附着甲基硫醇聚苯乙烯共…

基于PB的企业人力资源信息系统设计与实现

目 录 摘 要 I Abstract II 第1章 引言 1 1.1选题背景及意义 1 1.2发展现状 1 1.3论文结构 2 第2章 系统分析 3 2.1 系统目标 3 2.2 系统需求分析 3 第3章 系统设计 5 3.1 系统功能结构设计 5 3.2 数据库设计与实现 7 3.2.1数据库需求分析 7 3.2.2数据库概念结构设计 8 3.2.3数…

[oeasy]python0010 - python虚拟机解释执行py文件的原理

解释运行程序 🥊 回忆上次内容 我们这次设置了断点 设置断点的目的是更快地调试调试的目的是去除​​bug​​别害怕​​bug​​一步步地总能找到​​bug​​这就是程序员基本功 调试​​debug​​ 我心中还是有疑问 ​​python3​​ 是怎么解释​​hello.py​​ 的…

Python实现SSA智能麻雀搜索算法优化支持向量机分类模型(SVC算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种新型的群智能优化算法,在2020年提出&am…

pytorch:常见的pytorch参数初始化方法总结

pytorch参数初始化1. 关于常见的初始化方法1) 均匀分布初始化torch.nn.init.uniform_()2) 正态分布初始化torch.nn.init.normal_()3) 常量初始化torch.nn.init.constant_()4) Xavier均匀分布5)Xavier正态分布初始化6) kaiming均匀分布初始化7) kaiming正…

除了pid还有什么控制算法,类似pid算法还有哪些

什么是专家PID?他和传统的PID有什么区别? PID是智能控制啊,比如要控制一个水管的水流量,通过流量计,开关阀,让PID来控制开关阀的开关大小使水流量正确.专家PID记得是PID的高级设置,某些个场合一般的PID无法使用,出现了了专用的,有特殊功能的.记忆中是这…

防火墙的ISP选路

拓补图: 实验目的: 让R1走ISP1的路径访问192.168.1.1,R2走ISP2的路径访问172.16.1.1 1. IP地址的配置略 2. 防火墙区域的划分(防火墙的g1/0/2接口是属于ISP1接口,所以需要自己新建一个区域然后添加接口,…

测试界的飞虎队:测试人才战略——测试行业的精英战略(学习了)

一、前言 提到飞虎队,大家第一印象就是精英。相信绝大多数公司都希望能组件出一支优秀的测试队伍,来支撑自己的业务,很多公司都喊出了精英化战略。既然如此,就命中一个话题--测试人才战略。 有几个问题是不得不面对的&#xff1a…

算法 - 组合

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 剪枝优化 题目来源 77. 组合 - 力扣(LeetCode) 题目描述 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 输入&#…

JavaScript——关于JavaScript、在HTML中嵌入JS代码的三种方式、变量

前言 近日无意间透过装了热水之后,散发出水蒸气的透明水杯看东西时,发现看到的东西呈现模糊效果,这种效果和毛玻璃效果类似。毛玻璃效果在web、手机系统上也有很多应用,如网页上的广告弹窗,手机系统的消息通知界面等等…

LeetCode刷题复盘笔记——131. 分割回文串(一文搞懂回溯解决经典的分割回文串问题)

今日主要总结一下,131. 分割回文串 题目:131. 分割回文串 Leetcode题目地址 题目描述: 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读…

目标检测——day46 可转移交互性知识的人机交互检测

Transferable Interactiveness Knowledge for Human-Object Interaction Detection论文pdf下载(含笔记)Transferable Interactiveness Knowledge for Human-Object Interaction Detection1 INTRODUCTION3 PRELIMINARY4 METHOD4.1 Overview4.2 Representa…

JVM——类加载子系统

文章目录一、类加载器子系统作用二、类加载过程1、加载(Loading)2、验证(Verification)3、准备(Preparation)4、解析(Resolution)5、初始化(Initialization)三…