FreeRTOS-软件定时器

news2024/11/23 12:41:05

FreeRTOS-软件定时器

  • 一、软件定时器简介
    • 1.1 软件定时器的状态和工作模式
  • 二、软件定时器结构体成员和API函数
  • 三、软件定时器实验

一、软件定时器简介

  • 定时器:指定时间开始,经过一个指定的时间,触发一个超时事件,用户可自定义定时器的周期
  • 硬件定时器:硬件自带的定时器模块,精度高,定时时间到达以后可以触发中断,调用中断函数缺点个数有限
  • 软件定时器具有定时功能的软件,可设置定时周期,当指定时间到达后要调用回调函数(也称超时函数),用户在回调函数中处理信息,成本低,内存足够的情况下个数不限,但精度不高
  • 软件定时器特点:可裁剪configUSE_TIMERS配置成1使能定时器、支持设置单次定时器周期定时器
  • 软件定时器的超时回调函数是由软件定时器服务任务调用的,超时回调函数本身不是任务,不能在该回调函数中使用可能会导致任务阻塞的API函数
  • 软件定时器服务任务:在调用vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,叫软件定时器服务任务
  • 软件定时器服务任务作用:负责软件定时器超时的逻辑判断、调用超时软件定时器的超时回调函数、处理软件定时器命令队列
  • 软件定时器的API函数都是往定时器的队列中写入消息(发送命令),这个队列叫做软件定时器命令队列,提供给软件定时器使用,用户不能直接访问
  • 软件定时器配置:configUSE_TIMERS配置成1,在启动任务调度器时,会自动创建软件定时器的服务/守护任务prvTimerTask()。软件定时器服务任务的优先级为configTIMER_TASK_PRIORITY = 31,配置成最大。定时器的命令队列长度为configTIMER_QUEUE_LENGTH = 5

1.1 软件定时器的状态和工作模式

  • 软件定时器有两种状态休眠态-软件定时器可以通过其句柄被引用,但因为没有运行,所以其定时超时回调函数不会被执行。运行态-当指定时间到达以后,它的超时回调函数会被调用
  • 新创建的软件定时器处于休眠状态发送命令队列可以从休眠态变为运行态
  • 软件定时器的工作模式:单次定时器一旦定时超时,只会执行一次其软件定时器超时回调函数,不会自动重新开启定时,不过可以被手动重新开始。周期定时器-周期定时器的一旦启动以后就会在执行完回调函数以后自动的重新启动,从而周期的执行其软件定时器回调函数。

二、软件定时器结构体成员和API函数

  • 下面是软件定时器的结构体成员
typedef struct tmrTimerControl
{
		const char * pcTimerName;					//软件定时器名
        ListItem_t xTimerListItem;					//软件定时器列表项
        TickType_t xTimerPeriodInTicks;				//软件定时器周期
        void * pvTimerID;							//软件定时器ID
        TimerCallbackFunction_t pxCallbackFunction;	//软件定时器回调函数
        #if ( configUSE_TRACE_FACILITY == 1 )
            UBaseType_t uxTimerNumber;				//软件定时器编号
        #endif
        uint8_t ucStatus;							//软件定时器状态
} xTIMER;
  • 下面为软件定时器的相关API函数
xTimerCreate();				//动态创建软件定时器
xTimerCreateStatic();		//静态创建软件定时器
xTimerStart();				//开启软件定时器计时
xTimerStartFromISR();		//在中断中开启软件定时器计时
xTimerStop();				//停止软件定时器计时
xTimerStopFromISR();		//在中断中停止软件定时器计时
xTimerReset();				//复位软件定时器计时
xTimerResetFromISR();		//在中断中复位软件定时器计时
xTimerChangePeriod();		//更改软件定时器的定时超时时间
xTimerChangePeriodFromISR();//在中断中更改定时器超时时间
  • 下面为创建软件定时器函数
TimerHandle_t xTimerCreate(const char* const pcTimerName,
							const TickType_t xTimerPeriodInTicks,
							const UBaseType_t uxAutoReload,
							void* const pvTimerID,
							TimerCallbackFunction_t pxCallbackFunction);
//形参:定时器名 定时器超时时间 定时器模式 定时器ID 定时器超时回调函数
//返回值:判断是否创建成功
  • 下面为开启软件定时器函数
BaseType_t xTimerStart(TimerHandle_t xTimer,
						const TickType_t xTicksToWait);
//形参:待开启软件定时器句柄 发送命令最大等待时间
//返回值:开启是否成功
  • 下面为停止软件定时器函数
BaseType_t xTimerStop(TimerHandle_t xTimer,
						const TickType_t xTicksToWait);
//形参:待停止软件定时器句柄 发送命令最大等待时间
//返回值:停止是否成功
  • 下面为复位软件定时器函数
  • 该函数使软件定时器重新开启计时,复位后的软件定时器以复位时的时刻作为开启时刻重新定时
BaseType_t xTimerReset(TimerHandle_t xTimer,
						const TickType_t xTicksToWait);
//形参:待复位软件定时器句柄 发送命令最大等待时间
//返回值:复位是否成功
  • 下图为软件定时器时间步图,超时时候为t5时,在t3复位,则还需要到t8才超时

在这里插入图片描述

  • 下面为更改软件定时器超时函数
BaseType_t xTimerChangePeriod(TimerHandle_t xTimer,
								const TickType_t xNewPeriod,
								const TickType_t xTicksToWait);
//形参:待更新的软件定时器句柄 新的超时时间 发送命令的最大等待时间
//返回值:是否更改成功

三、软件定时器实验

  • 实验设计:设计两个任务,start_task:创建task1和两个定时器-单次和周期。task1:按键扫描,对定时器进行开启、停止操作。
#define configSUPPORT_DYNAMIC_ALLOCATION					1//动态创建任务/信号量宏定义配置
#define configUSE_TIMERS		1//使能软件定时器
#define configTIMER_TASK_PRIORITY	31//最高优先级
#define configTIMER_QUEUE_LENGTH	5//队列长度
#define configTIMER_TASK_STACK_DEPTH	256//定时器任务堆栈

//start_task参数宏定义
#define	START_TASK_STACK_SIZE 								128//堆栈大小
#define	START_TASK_PRIO										1//任务优先级
TaskHandle_t	start_task_handle;							//任务句柄
//task1参数宏定义
#define	TASK1_STACK_SIZE 									128//堆栈大小
#define	TASK1_PRIO											2//任务优先级
TaskHandle_t	task1_handle;								//任务句柄


//task1任务函数:按键扫描,对定时器进行开启,停止操作
void task1( void * pvParameters )
{
		uint8_t KeyNum = 0;
		while(1)
		{
			KeyNum = Key_GetNum();
			if(KeyNum == 1)//key0按下
			{
				xTimerStart(timer1_handle,portMAX_DELAY);//开启单次定时器1
				xTimerStart(timer2_handle,portMAX_DELAY);//开启周期定时器2
			}
			else if(KeyNum == 2)//Key1按下
			{
				xTimerStop(timer1_handle,portMAX_DELAY);//关闭单次定时器1
				xTimerStop(timer2_handle,portMAX_DELAY);//关闭周期定时器2
			}
			vTaskDelay(10);//自带延时函数
		}
}


//单次定时器超时回调函数
void timer1_callback(TimerHandle_t pxTimer)
{

}
//周期定时器超时回调函数
void timer2_callback(TimerHandle_t pxTimer)
{		

}

TimerHandle_t timer1_handle = 0;//单次定时器句柄
TimerHandle_t timer2_handle = 0;//周期定时器句柄
//Start_task任务函数:创建task1和两个定时器-单次和周期
void Start_task( void * pvParameters )
{
		taskENTER_CRITICAL();//进入临界区
		//创建定时器
		timer1_handle = xTimerCreate("timer1",1000,pdFALSE,1,timer1_callback);//单次定时器1s
		timer2_handle = xTimerCreate("timer2",1000,pdTRUE,2,timer2_callback);//周期定时器1s
		//创建任务1
		xTaskCreate(task1,//任务函数
					"task1",//任务名称
					TASK1_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					TASK1_PRIO,//优先级
					&task1_handle//任务句柄
					);
		vTaskDelete(start_task_handle);
		//删除自身任务Start_task,start_task_handle或NULL都可以
		taskEXIT_CRITICAL();//退出临界区
}


void freertos_demo()
{
		xTaskCreate(Start_task,//任务函数
					"Start_task",//任务名称
					START_TASK_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					START_TASK_PRIO,//优先级
					&start_task_handle//句柄
					);//创建Start任务
		vTaskStartScheduler();//开启任务调度器,开启执行Start任务
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ThinkPHP5bootstrapMySQL开发学习平台(包括后台管理功能、PC端网页、移动端网页)手把手运行源码

一、项目预览(全部源码链接在最下面) 功能及页面持续优化中...... 二、本地运行方式 1、下载源码包进行解压(源码在最下面) 2、下载phpstudy_pro,并运行Apache&

精华帖分享 | 判定策略失效的新方法——统计假设检验

本文来源于量化小论坛策略分享会板块精华帖,作者为元亨利贞,发布于2023年12月25日。 以下为精华帖正文: 1、起因 去年刚入门B圈,由于之前有做商品期货择时的经验,通常来讲,趋势跟随,并且回测结…

谁说电商选品找货源没有捷径,只要你用对工具!

最近跟很多同行聊,都在抱怨选品难的问题,都说7分靠选品,3分靠运营,对于选品来说,并没有捷径可走,但其实是有很多不同的角度的。 现在市面上大部分开发做的选品,“选品方法”或“产品分析方法”…

SiLM266x系列SiLM2661高压电池组前端充/放电高边NFET驱动器 为电池系统保护提供可靠性和设计灵活性

SiLM2661产品概述: SiLM2661能够灵活的应对不同应用场景对锂电池进行监控和保护的需求,为电池系统保护提供可靠性和设计灵活性。是用于电池充电/放电系统控制的低功耗、高边 N 沟道 FET 驱动器,高边保护功能可避免系统的接地引脚断开连接&am…

Pycharm连接AutoDL服务器 文件上传 启动终端

Pycharm AutoDL 需要使用pycharm专业版(学生可以通过教育邮箱认证,每年一次)。 首先进入AutoDL官网:AutoDL-品质GPU租用平台-租GPU就上AutoDL进行学生注册登录(可以领10元的代金券)点击右上角的控制台&am…

京东web 京东e卡绑定 第二部分分析

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 有相关问题请第一时间头像私信联系我删…

api测试和接口测试的区别

API测试和接口测试是软件测试中一个非常重要的领域,尤其是在当前Web应用程序和移动应用程序的发展中。虽然它们都测试了Web服务的功能,但是二者在测试方法和测试实施方面存在很大的差异。本文将介绍API测试和接口测试之间的主要区别 API测试的主要关注点…

【WebGis开发 - Cesium】三维可视化项目教程---图层管理基础

目录 引言一、功能设计1. 主体功能2. 细节问题 二、代码实现1. 树形控件2. 全局状态准备3. 创建图层控制方法3.1 加载、卸载方法编写3.2 统一对外暴露入口3.3 提供图层类别的可拓展性3.1 完整代码 4. 效果展示5. hooks函数使用方法 三、总结 引言 本教程主要是围绕Cesium这一开…

华为云服务器公网ip访问不通解决

问题:用弹性公网IP登录超时,ping不通,但是VNC方式可以登陆成功 解决:执行ifconfig,看到eth0网卡没有获取到 ifconfig 执行dhclient自动获取下网卡 : dhclient 再次执行ifconfig:网卡已经获…

【AI论文精读3】RAG论文综述1-P1

AI知识点总结:【AI知识点】 AI论文精读、项目、思考:【AI修炼之路】 简介 论文中英文名 Retrieval-Augmented Generation for Large Language Models: A Survey 面向大型语言模型的检索增强生成:综述 论文地址 arxiv地址:http…

知识蒸馏介绍

一、知识蒸馏介绍 1.1 概念介绍 知识蒸馏(knowledge distillation)是模型压缩的一种常用的方法,不同于模型压缩中的剪枝和量化,知识蒸馏是通过构建一个轻量化的小模型,利用性能更好的大模型的监督信息,来…

项目经理是怎么慢慢废掉的?这些无意识行为可能会毁了你!

工作久了,每个人都或多或少会有一些无力感和疲惫感。如果没有调整过来,久而久之,会感觉自己好像废掉了,做什么事情都打不起精神。 如果你是项目经理,工作中有这样一些迹象,比如总是拖延时间、丧失自己的判…

【进程间通信(三)】【system V共享内存】

目录 1. 原理2. 编码通信2.1 创建共享内存2.2 shmat && shmdt && shmctl2.3 通信 3. 共享内存的特性3.1 共享内存的属性3.2 加入管道实现同步机制 前面的文章介绍了管道通信,其中包括匿名管道、命名管道。这篇文章介绍另一种进程间通信的方式 -----…

NVP的含义?如何理解其在AEM|FLUKE线缆认证测试中的意义?不同的NVP会出现怎样的结果?

在AEM|FLUKE铜缆认证测试中,有很多朋友对NVP设置有疑问,不知道应该怎么去设置它,并很好的应用它,那我们基于此,做一个简单的分析。 什么是NVP? NVP是Nominal Velocity of Propagation的缩写?简单直接译过…

Java基础-泛型机制

文章目录 为什么引入泛型泛型的基本使用泛型类泛型接口泛型方法泛型数组正确的数组声明使用场景如何理解Java中的泛型是伪泛型?泛型中类型擦除 泛型数组:如何正确的初始化泛型数组实例? 为什么引入泛型 引入泛型的意义在于: 适用…

KEYSIGHT B1500A 半导体器件参数分析仪

新利通 B1500A 半导体器件参数分析仪 ——一体化器件表征分析仪—— 简述 Keysight B1500A 半导体参数分析仪是一款一体化器件表征分析仪,能够测量 IV、CV、脉冲/动态 IV 等参数。 主机和插入式模块能够表征大多数电子器件、材料、半导体和有源/无源元器件。 B…

关于相机的一些零碎知识点

热成像,英文为Thermal Imaging,例如型号500T,其实指的就是热成像500分辨率。 相机的CMOS,英文为Complementary Metal Oxide Semiconductor,是数码相机的核心成像部件,是一种互补金属氧化物导体器件。 DPI…

PVC刻字膜高精度模切应用

PVC刻字膜是一种由聚氯乙烯(PVC)为主要成分制成的薄膜材料,具有耐磨、耐刮、耐水、耐油以及良好的化学稳定性等特点。这种薄膜在多个行业中得到广泛应用,特别是在服装、鞋业、箱包、汽车内饰等领域,用于制作各种标识、…

NDC美国药品编码目录数据库查询方法

NDC(National Drug Code)翻译为“国家药品代码”,是美国食品药品监督管理局(FDA)制定的一种药品标识系统,用于唯一标识药品。这个编码系统主要目的是为精准识别和追踪不同药品而建设,行业人员和…