FreeRTOS软件定时器(1-18)

软件定时器简介

定时器:从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可以自定义 定时器周期。

硬件定时器:芯片本身自带的定时器模块,硬件定时器的精度一般很高,每次在定时时间到之后自动触发中断,用户在中断服务函数中处理信息。

软件定时器:具有定时功能的软件,可以设置定时周期,当指定时间到达后调用回调函数,(可以称之为超时函数),用户在回调函数中处理信息。

软件定时器的优缺点

优点:

1:硬件定时器数量有限,软件定时器理论上只需要有足够的内存,就可以创建多个

2:使用简单,成本低

缺点:

1:软件定时器相对于硬件定时器来说,精度不高(因为它以系统时钟为基准,系统时钟中断优先级最低,容易被打断),对于需要高精度要求的场合,不建议使用软件定时器。

 软件定时器的特点

1:可以裁剪,软件定时器是可裁剪可配置功能,如果要使用软件定时器,需要将configUSE_TIMERS 配置为 1。

2:单次和周期,软件定时器支持设置为:单次定时器周期或周期定时器

注:

1:软件定时器超时回调函数是由软件定时器服务任务调用的,软件定时器超时回调函数不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的API函数。

2:软件定时器服务任务:在调用函数vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,这个任务就叫做软件定时器服务任务。

软件定时器服务任务作用

1:可以裁剪,软件定时器是可裁剪可配置功能,如果要使用软件定时器,需要将configUSE_TIMERS 配置为 1。

2:单次和周期,软件定时器支持设置为:单次定时器周期或周期定时器

注:

1:软件定时器超时回调函数是由软件定时器服务任务调用的,软件定时器超时回调函数不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的API函数。

2:软件定时器服务任务:在调用函数vTaskStartScheduler()开启任务调度器的时候,会创建一个用于管理软件定时器的任务,这个任务就叫做软件定时器服务任务。

软件定时器服务任务作用

1:负责软件定时器超时的逻辑判断

2:调用超时软件定时器的超时回调函数

3:处理软件定时器的命令队列

【软件定时器在开始创建的时候处于休眠状态,要通过命令队列唤醒工作】

软件定时器命令队列

FreeRTOS提供了许多软件定时器相关的API函数,这些API函数大多都是往定时器的队列中写入消息(发送命令),这个队列叫做软件定时器命令队列,是提供给FreeRTOS中的软件定时器使用的,用户是不能直接访问的。

【往软件定时器发送一个命令】

软件定时器相关配置

1:宏定义配置,当freeRTOS的配置项configUSE_TIMERS 设置为 1,在启动任务调度器时,会自动创建软件定时器的服务/守护任务preTimerTask();

2:软件定时器服务任务优先级configTIMER_TASK_PRIORITY = 31

3: 定时器的命令长度为configTIMER_QUEUE_LENGTH = 5;

注:

软件定时器的超时回调函数是在软件定时器服务任务中被调用的,服务任务不是专门为某个定时器服务,它还要处理其他定时器。

so:

1:定时器回调函数要尽快实行,不能进入阻塞状态,即不能调用那些会阻塞任务的API函数,如vTaskDelay();

2:访问队列或者信号量的非零阻塞时间的API函数也不能调用

软件定时器的状态

1:休眠态,软件定时器可以通过其句柄被引用,但是因为没有运行,所以其定时超时回调函数不会被执行。

2:运行态,指定的定时时间到达之后,它的超时回调函数会被调用

注:

1:新创建的软件定时器处于休眠的状态,是没有运行的

2:通过发送命令队列的方式可以让软件定时器从休眠的状态转换为运行的状态

单次定时器和周期定时器

FreeRTOS提供了两种软件定时器

1:"单次定时器" ,一旦定时超时,只会执行一次其软件定时器超时回调函数,不会自动重新开启定时,不过可以被手动重新开启。

2:"周期定时器",周期定时器一旦启动以后就会执行完回调函数后自动重新启动,从而周期的执行其软件定时器回调函数。

软件定时器状态转换图

软件定时器结构体成员

typedef struct{const char *            pcTimerName            /*软件定时器名字*/ListItem_t              xTimerListItem         /*软件定时器列表项*/TickType_t              xTimerPeriodInTicks    /*软件定时器的周期*/void *                  pvTimerID              /*软件定时器ID*/TimerCallbackFunction_t pxCallbackFunction     /*软件定时器回调函数*/#if(configUSE_TRACE_FACILITY == 1)UBaseType_t              uxTimerNumber     /*软件定时器的编号*/#endifuint8_t                      ucStatus          /*软件定时器的状态*/}xTIMER;

软件定时器API函数

函数描述
xTimerCreadte()动态方式创建软件定时器
xTimerCreateStatic()静态方式创建软件定时器
xTimerStart()开启软件定时器定时
xTimerStartFromISR()在中断中开启软件定时器定时
xTimerStop()停止软件定时器定时
xTimerStopFromISR()在中断中停止软件定时器定时
xTimerReaet()复位软件定时器定时
xTimerResetFromISR()在中断中复位软件定时器定时
xTimerChangePeriod()更改软件电视器定时超时时间
xTimerChangePeriodFromISR()在中断中更改定时超时时间

创建软件定时器

要使用定时器,需要先创建它,得到它的句柄。 有两种方法创建定时器:动态分配内存、静态分配内存。函数原型如下:

/*使用动态分配内存的方式创建软件定时器*	pcTimerName:定时器名字, 用处不大, 尽在调试时用到*	xTimerPeriodInTicks: 周期, 以Tick为单位*	uxAutoReload: 类型, pdTRUE表示自动加载, pdFALSE表示一次性*	pvTimerID: 回调函数可以使用此参数, 比如分辨是哪个定时器*	pxCallbackFunction: 回调函数*	返回值: 成功则返回TimerHandle_t, 否则返回NULL
*/
TimerHandle_t xTimerCreate( const char * const pcTimerName,const TickType_t xTimerPeriodInTicks,const UBaseType_t uxAutoReload,void * const pvTimerID,   TimerCallbackFunction_t pxCallbackFunction  );/*
静态创建软件定时器
*	pcTimerName:定时器名字, 用处不大, 尽在调试时用到
*	xTimerPeriodInTicks: 周期, 以Tick为单位
*	uxAutoReload: 类型, pdTRUE表示自动加载, pdFALSE表示一次性
*	pvTimerID: 回调函数可以使用此参数, 比如分辨是哪个定时器
*	pxCallbackFunction: 回调函数
*	pxTimerBuffer: 传入一个StaticTimer_t结构体, 将在上面构造定时器
*	返回值: 成功则返回TimerHandle_t, 否则返回NULL
*/
TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,TickType_t xTimerPeriodInTicks,UBaseType_t uxAutoReload,void * pvTimerID,TimerCallbackFunction_t                                                pxCallbackFunction,  StaticTimer_t                                      *pxTimerBuffer);

开启定时器的API函数

BaseType_t xTimerStart(TimerHandle_t    xTimer,const TickType_t xTicksToWait);/*参数含义xTimer       待开启软件定时器句柄xTickToWait  发送命令到软件定时器命令队列的最大等待时间返回值PSPASS       软件定时器开启成功pdFALSE      软件定时器开启失败*/

停止软件定时器的API函数

BaseType_t xTimerStop(TimerHandle_t xTimer,const TickType_t xTickToWait
);
/*参数含义xTimer          待停止的软件定时器句柄xTickToWait     发送命令到软件定时器命令队列的最大等待时间返回值PdPASS          停止成功pdFALSE         停止失败
*/

复位软件定时器

该功能将使软件定时器的重新开启定时,复位后的软件定时器以复位时的时刻作为开启时刻重新定时,(按下复位键之后,重新开始从原来的时间继续计时)。

BaseType_t xTimerReset(TimerHandle_t    xTimer,const TickType_t xTickToWait
);
/*参数含义xTimer        待复位的软件定时器句柄xTickToWait   发送命令到软件定时器命令队列的最大等待时间返回值PdPASS          软件定时器复位成功pdFALSE         软件定时器复位失败
*/

更改软件定时器超时时间API函数

BaseType_t xTimerChangePeriod(TimerHandle_t     xTimer,const TickType_t  xNewPeriod,const TickType_t  xTicksToWait
);
/*定时器参数xTimer     待更新的软件定时器句柄xNewPeriod 新的定时器超时时间,单位:系统时钟节拍xTickToWait 发送命令到软件定时器命令队列的最大等待时间返回值PdPASS          软件定时器定时超时时间修改成功pdFALSE         软件定时器定时超时时间修改失败
*/

软件定时器项目实战

【参考自正点原子视频和伟东山老师文档】

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

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

相关文章

Java常用命令总结 持续更新中!!!

蓝桥杯JAVA组 推荐输入输出示例 // 基础输入 import java.util.*;public class Main{public static void main(String[] args){} }// 非静态方法调用 new Main.Solution();//static函数里面调用非static函数 类.函数// 更快的输入方式 BufferedReader // 更快的输出方式 Print…

js监听页面的显示和隐藏

下方微信公众号 和微信小程序推荐 js监听页面的显示和隐藏 在JavaScript中,监听页面的显示和隐藏可以通过监听visibilitychange事件来实现。visibilitychange事件会在页面的可见性发生变化时触发。 以下是一个简单的示例,演示如何使用visibilitychan…

《面向对象程序设计及C++》实验报告

《面向对象程序设计及C》实验报告 一、实验目的与实验要求 (1)掌握类的定义、类中成员函数的定义和使用、构造函数和析构函数的定义、功能;掌握对象的使用方法。 (2)掌握静态数据成员、静态成员函数的功能和使用方法…

Linux —— 信号初识

Linux —— 信号初识 什么是信号测试几个信号signal函数函数原型参数说明返回值注意事项示例 后台程序前台转后台检测输入中断向量表 我们今天来继续学习Linux的内容,今天我们要了解的是Linux操作系统中的信号: 什么是信号 信号是操作系统内核与进程之…

判断dll/lib是32/64位、查看lib是导入库/静态库的方法 、查看dll包含的符合、lib包含的函数

一、判断dll/lib是32/64位 原文链接:https://www.cnblogs.com/bandaoyu/p/16752602.html 1. 简便方法: 直接用记事本或者notepad(或txt文本)打开exe文件(dll文件),会有很多乱码,不要头疼,接下…

Vitis HLS 学习笔记--Schedule Viewer 调度查看器

目录 1. 简介 2. Schedule Viewer详解 2.1 视图说明 2.1.1 Operation\Control Step 2.1.2 周期关系图 2.1.3 Schedule Viewer 菜单栏 2.1.4 属性视图 2.2 内容说明 2.2.1 实参(b)解释 2.2.2 实参(a)解释 2.2.3 变量&am…

Windows如何安装hadoop

Hadoop是一个开源的分布式计算平台,旨在处理大规模数据的存储和处理。它提供了分布式文件系统(HDFS)和分布式计算框架(MapReduce),使得用户能够在大规模集群上存储和处理数据。Hadoop最初由Apache软件基金会…

cmake进阶:定义函数的使用方法

一. 简介 前面已经将 cmake 中常用的命令 command、变量 variable 都给大家进行了详细介绍,通过前面的学习,相信大家已经掌握了 cmake 工具的基本使用方法; 接下来我们再进一步学习 cmake,本文开始学习 cmake中定义函数。 二. …

TypeScript学习日志-第十九天(namespace命名空间)

namespace命名空间 一、基本用法 namespace 所有的变量以及方法必须要导出才能访问,如图: 二、 嵌套 namespace 可以进行嵌套使用,如图: 它也必须需要导出才能访问 三、合并 当我们出现两个同名的 namespace 它就会合并这两…

EFDC模型安装及建模方法;在排污口论证、水质模拟、地表水环评、地表水水源地划分、水环境容量计算等领域中的应用

目录 专题一 EFDC软件安装 专题二 EFDC模型讲解 专题三 一维河流模拟实操 专题四 建模前处理 专题五 EFDC网格剖分介绍 专题六 EFDC二维湖库水动力模拟/非保守染色剂模拟 专题七 EFDC水质模型参数及原理介绍 专题八 EFDC一、二、三维湖库水质模拟 专题九 基于EFDC的地…

nodejs的ws+vue3编写聊天室的demo

nodejs编写ws服务是非常简单高效的,nodejs有众多的实现ws的库,如ws,SocketIO等,nodejs的事件线程是单线程的,所以不要在事件线程内做阻塞性的操作,耗时的操作交给工作线程或者子进程操作。 我使用nodejsvue3实现了写了…

408数据结构-二叉树的遍历 自学知识点整理

前置知识:二叉树的概念、性质与存储结构 二叉树的遍历 二叉树的遍历是指按某条搜索路径访问树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。 二叉树的递归特性: ①要么是棵空二叉树; ②要么就是由“根节点左子树右子树…

【NOI】C++程序结构入门之分支结构二

文章目录 前言一、逻辑运算符1.导入2.逻辑与(&&)3.逻辑或(||)4.逻辑非(!) 二、例题讲解问题:1656. 是两位的偶数吗问题:1658. 游乐设施问题:1659. 是否含有数字5…

AI绘画:Stable Diffusion 拒绝一眼塑料味的AI质感,超写实人物图片如何制作?简单几步教会你!

今天给大家介绍一款能够对生成的人像进行皮肤调节的 lora。 上面两幅图片的生成参数一样,尺寸也一样,但右边一幅图片相较于左面图片的画面质感,特别是人像皮肤的质感上有很大的提升,看上去更加细腻有层感。 这就是我们今天要介绍…

linux下的调试工具gdb的详细使用介绍

在之前学习中我们使用的通常是集各种功能于一体的编译器,例如VS stdio,但是一个程序在编辑后还要进行编译,然后才能产生一个二进制的可执行文件,编辑和翻译工作都可以使用不同的软件进行,例如记事本就是一款编辑软件&a…

03.配置监控一台服务器主机

配置监控一台服务器主机 安装zabbix-agent rpm -ivh https://mirror.tuna.tsinghua.edu.cn/zabbix/zabbix/4.0/rhel/7/x86_64/zabbix-agent-4.0.11-1.el7.x86_64.rpm配置zabbix-agent,配置的IP地址是zabbix-server的地址,因为要监控这台主机 vim /etc/zabbix/zab…

免费开源线上线下交友社交圈子系统 小程序+APP+H5 可支持二开!

为什么要玩社交软件:互联网社交软件的独特优势 首先,社交软件为我们提供了一个便捷的沟通方式。在传统的交往方式中,人们需要面对面交流,这种方式在时间和空间上都受到限制。而社交软件打破了这些限制,无论我们身处何地…

既能自动仿写公众号爆文,还能批量帮你上架闲鱼商品,打造自己的数字员工,简直yyds

「想象一下,如果有一个机器人在你的计算机上24小时不间断地工作,会不会做梦都笑着」 一、RPA机器人是什么? RPA——机器人流程自动化,它可以帮助人们完成重复性的、繁琐的工作,比如数据输入、网页爬取、自动化流程等…

llama3 史上最强开源大模型,赶超GTP-4,逼宫OpenAI

2024年4月18日,Meta公司推出了开源大语言模型Llama系列的最新产品—Llama 3,包含了80亿参数的Llama 3 8B和700亿参数的Llama 3 70B两个版本。Meta称其为“迄今为止最强的开源大模型”。 怪兽级性能 LLaMA3 提供了不同参数规模的版本,以适应…

你真的知道Show Master Status吗?

欢迎来到我的博客,代码的世界里,每一行都是一个故事 你真的知道Show Master Status吗? 前言输出字段展示file详解Position详解Binlog_Do_DBBinlog_Ignore_DBExecuted_Gtid_Set 前言 在数据库的世界里,每一个字段都像是一个谜团&a…