FreeRTOS(三)

第二部分 事件组

一、事件组的简介

1、事件

事件是一种实现任务间通信的机制,主要用于实现多任务间的同步,但事件通信只能是事件类型的通信,无数据传输。其实事件组的本质就是一个整数(16/32位)。可以是一个事件发生唤醒一个任务,或者多个事件唤醒一个或多个任务。

2、与队列/信号量的区别:

①信号量/队列当事件发生时只去唤醒一个任务,而事件组可唤醒多个任务,起到一个广播的作用。 ②信号量/队列是一个消耗性资源,即数据读走了就减少,而事件组可以选择清除事件也可以选择保留事件。 ③事件组只能是起到一个同步的作用,并不能传递数据。 ④事件组可以实现多个任务之间的同步,队列/信号量则只能是两个任务之间的同步。

3、事件组

1)整数的位数: 如果宏configUSE_16_BIT_TICKs = 0,那么这个整数是32位的,其中⽤低24位来表示事件组,代表24 个事件,剩余8位用于管理事件。 如果宏configUSE_16_BIT_TICKs = 1,那么这个整数是16位的,其中⽤低8位来表示事件组,代表8个事 件。

2)每⼀位事件的含义由我们自己定义。

3)这些位,值为1表示事件发生了,值为0表示事件没发⽣。

4)⼀个或多个任务、ISR都可以写这些位。

5)⼀个或多个任务可以等待某⼀位、某几个位。

特点

①与信号量不同设置,事件组不会阻塞,多个任务设置同一时间等于设置一次。

②支持事件超时等待机制,等待该事物类型的任务会进行阻塞态

③逻辑与:任务所期望的事件全部发生,任务才能被唤醒

逻辑或:任务所期望的事件只要有任意一个事件发生,任务即可被唤醒。

全局变量的区别

1.全局变量使用在操作系统中存在被多个任务同时读写的风险,则事件组它会直接禁止任务调度来规避风险。 2.使用全局变量需要自己去实现阻塞机制(成本太高)。 3.使用事件组能更方便的实现多任务之间的同步。

二、API函数

接口函数函数功能
xEventGroupCreate()动态创建事件组
xEventGroupSetBits()事件组置位函数
xEventGroupWaitBits()等待事件函数
EventGroupHandle_t()事件组结构体
EventGroupHandle_t
xEventGroupCreate

分三步:①为事件组结构体分配内存

②初始化事件组

③初始化等待链表

xEventGroupSetBits()

xEventGroupWaitBits

 

 

第三部分 软件定时器

一、简介

1、硬、软定时器

硬件定时器:由外部晶振提供时钟,定时精准,精度可以达到微秒级。不仅具有定时功能,还可以输出PWM,输入捕获等高级功能,当时间到达会触发一次中断。

软件定时器:基于一个守护任务,可以被其他中断或优先级比它高的任务打断,且软件定时器的精度是基于系统时钟SysTick的,一般达不到微秒级别。只能用来定时,每当时间到达会执行回调函数。

2、为何使用软件定时器

硬件定时器数量有限,而且使用定时的高级功能一般不会用来定时,但是实际上需要很多定时器来采集数据,上传数据等,所以我们就有了软件定时器,只要内存足够可以创建无数个软件定时器(一个软件定时器只需要一个定时器结构体的内存,还需要两条定时器链表,一个队列)。

软件定时器适合于对定时器精度要求不高的周期性任务

二、API函数

接口函数函数功能
tmrTimerControl定时器结构体
xTimerCreate()创建定时器
xTimerStart()启动定时器
xTimerStop()停止定时器
xTimerDelete()删除定时器
1、tmrTimerControl

(定时器结构体)

(1)定时器周期

单次定时:像闹钟一样只执行一次,时间一到事情做完定时器就停止运行;

周期定时:比如每隔20s触发一次,这就是周期执行。

(2)回调函数

每个定时器都由用户指定一个回调函数(功能由用户自己实现),每当定时器超时,守护任务则会去调用该定时器的回调函数

typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer );

(3)定时器的状态

定时器活跃:定时器并不是一被创建就开始定时,与硬件定时器一样需要一个启动的命令(当前任务通过消息队列发送给守护任务),则定时器才会被挂入定时器链表,则处于活跃态,假设一个定时器是单次定时,在一次定时之后,则定时器会被移出定时器链表,所以判断一个定时器是否在活跃态,就是判断定时器是否在定时器链表中(如果在说明该定时器在参与定时)。

(4)软件定时器的守护任务

通过一个prvTimerTask任务来管理软件定时器,这个任务也叫“守护任务”。在启动调度器时自动创建的,以满足用户定时的需要。

需要在config文件中将configUSE_TIMERS设置为1时,在启用调度器时自动创建守护任务。

(5)定时器命令队列

任务和守护任务之间通过消息队列,守护任务创建完成后将会进入阻塞状态,等待用户程序发起定时器启动命令。其阻塞时间为定时器定时时间。

2、xTimerCreate()

第一次创建定时器需要初始化两条定时器链表(一条正常,一条超时),并创建一个消息队列,以上三者是软件定时器运行起来的基本配置。

守护任务:如果将宏configUSE_TIMERS配置为1则默认使用定时器,回创建一个定时器的守护任务。

3、xTimerStart()
定时器命令ID:

ID号-2~-1:直接调用用户指定的函数在守护任务执行前

ID号0~5:定时器的启动、复位、停止、更改周期、删除命令

ID号6~9:中断版的定时器的启动、复位、停止、更改周期命令

作用:将定时器信息打包发送给定时器信息队列等待守护任务读取信息并处理。

4、xTimerStop()

不难发现他的内部函数还是那个,只是执行命令不同。

5、xTimerDelete()

三、运行机制

(1)创建定时器--创建定时器控制块

用户程序调用定时器创建函数,给出定时时间

SysTick定时器常被用来作为软件定时器的时钟源,1s节拍1000次,1次就是1ms

(2)插入列表

根据定时时间长短:以升序方式插入链表中。

有两个链表:一个是创建时插入表,另一个是溢出时插入表。

xTimeNow:这个是SYSTIC的计数值。

XTicksToWait:xTimeNow+定时时间。

(3)启动定时器

当⽤户任务发送定时器启动命令后,定时器的守护任务函数将会执⾏。在任务函数中定义了⼀个全

局变量并初始化为0,⽤来保存上次定时器时间到的SYSTICK的值。

然后,⽐较全局变量和当前xTimeNow的值,如果xTimeNow<上次SYSTICK,则表明SYSTICK溢

出,那么将会把第⼀张链表上的定时器移到第⼆张链表中。

如果系统节拍计数器没有溢出,⽐较xTimeNow 和 xTickToWait的值,当xTimeNow >=

xTickToWait时,说明定时器时间到,调⽤回调函数。

如果xTimeNow <xTickToWait,定时器任务阻塞,阻塞时间为:xTickToWait - xTimeNow时。

以上是目前我对FreeRTOS的理解,后续如果对这块有更深理解会继续更新,如果有错误的地方可以交流。

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

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

相关文章

微服务(基础篇-006-Docker)

Docker是一个开源的应用容器引擎&#xff0c;它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何Linux机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间没有任何接口&#xff08;类似 iPhone 的 app&…

【晴问算法】入门篇—递归—汉诺塔

题目描述 汉诺塔(又称河内塔)问题源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定&#xff0c;在小圆盘…

Count Color 线段树统计颜色

线段树统计颜色 先压位存储 类似一个bitset 输出答案的时候看看有几个1就好了 pushup的话或一下左右区间 #include<iostream> #include<cstring> using namespace std;const int N 1e610;struct Segment{int l,r,id,lz; }tr[N<<2];void pushup(int u){t…

oracle19c adg搭建

一、环境搭建 主机IPora19192.168.232.111ora19std192.168.232.112 本文结合&#xff1a;https://blog.csdn.net/weixin_63131036/article/details/136635553 1.配置网络yum源 1.删除redhat7.0系统自带的yum软件包&#xff1b; rpm -qa|grep yum >oldyum.pkg 备份原信息 …

工作12年了,我还没能过上自己想要的生活

写这篇文章之前&#xff0c;我想了很久&#xff0c;不知道该如何下笔&#xff0c;如何向读者说明这些年我是怎么走过来的&#xff0c;我只是依稀的记得当时的自己犹如在昨天。 2009年大学毕业&#xff0c;我和大多数的毕业生一样写简历求职。不管是招聘会还是网上投简历&#x…

YOLOv9改进策略:卷积魔改 | DCNv2升级版本,助力检测

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;在DCN的基础上&#xff0c;增加了2个创新点&#xff0c;分别是调制模块和使用多个调制后的DCN模块&#xff0c;从形成了DCN的升级版本——DCNv2 &#x1f4a1;&#x1f4a1;&#x1f4a1;如何使用&#xff1a…

循环神经网络(RNN):处理序列数据的利器

目录 1. 引言 2.RNN原理与时间步展开 3.LSTM与GRU工作机制与优势 3.1.LSTM&#xff08;Long Short-Term Memory&#xff09; 3.2.GRU&#xff08;Gated Recurrent Unit&#xff09; 4.应用案例 4.1文本生成 4.2情感分析 5.总结 1. 引言 循环神经网络&#xff08;Recurr…

UE5学习日记——Rope Swing 人物与绳索摆动知识准备

rope swing荡绳 比我想的要复杂&#xff0c;目前还没查到简单的做法。本文为查资料的记录&#xff0c;积累后再做一个自己满意的荡绳蓝图。 一、某国外网友的解释 原文 https://forums.unrealengine.com/t/implementing-rope-swing/83098/15 Project Flake - Physics Rope De…

JavaScript Uncaught ReferenceError: WScript is not defined

项目场景&#xff1a; 最近在Visual Studio 2019上编译libmodbus库&#xff0c;出现了很多问题&#xff0c;一一解决特此记录下来。 问题描述 首先就是configure.js文件的问题&#xff0c;它会生成两个很重要的头文件modbus_version.h和config.h&#xff0c;这两个头文件其中…

软件测试过程中如何有效的开展接口自动化测试

一.简介 接口自动化测试是指使用自动化测试工具和脚本对软件系统中的接口进行测试的过程。其目的是在软件开发过程中&#xff0c;通过对接口的自动化测试来提高测试效率和测试质量&#xff0c;减少人工测试的工作量和测试成本&#xff0c;并且能够快速发现和修复接口错误&…

使用Qt生成图片

Qt之生成png/jpg/bmp格式图片_qt生成图片-CSDN博客 (1)使用QPainter 示例关键代码&#xff1a; QImage image(QSize(this->width(),this->height()),QImage::Format_ARGB32);image.fill("white");QPainter *painter new QPainter(&image);painter->…

关于振弦式渗压计的基本知识详解

振弦式渗透压力计的组成主要包括振弦、高灵敏度金属薄膜、渗透石以及激励和接收线圈等。其运作机制是&#xff1a;水压力施加在金属薄膜上导致其形变&#xff0c;进而影响连接的钢弦的拉力。由于钢弦振动频率与其拉力密切相关&#xff0c;通过测量钢弦的频率变化即可计算出渗透…

Python更改Word文档的页面大小

页面大小确定文档中每个页面的尺寸和布局。在某些情况下&#xff0c;您可能需要自定义页面大小以满足特定要求。在这种情况下&#xff0c;Python可以帮助您。通过利用Python&#xff0c;您可以自动化更改Word文档中页面大小的过程&#xff0c;节省时间和精力。本文将介绍如何使…

【React】react 使用 lazy 懒加载模式的组件写法,外面需要套一层 Loading 的提示加载组件

react 组件按需加载问题解决 1 错误信息2 解决方案 1 错误信息 react 项目在创建 router 路由时&#xff0c;使用 lazy 懒加载时&#xff0c;导致以下报错&#xff1a; The above error occurred in the <Route.Provider> component:Uncaught Error: A component suspe…

秒杀VLOOKUP函数,查找数字我只服SUMIF函数

一提到数据查询&#xff0c;相信很多人的第一反应就是使用Vlookup函数。但是今天我想跟大家分享另一种比较另类的数据查询方式&#xff0c;就是利用SUMIF函数&#xff0c;相较于Vlookup函数它更加的简单灵活、且不容易出错&#xff0c;下面我们就来学习下它的使用方法。 1、常…

【基础知识】HTTP协议中“POST“和“GET”两种请求方式区别

0x01:两种方法对比 在我们客户端与服务器之间进行请求和响应的时候&#xff0c;最常用的两种方法是&#xff1a;GET和POST POST —— 向指定的资源提交要被处理的数据。 GET —— 向指定的资源请求数据 GET请求参数呢一般显示在URL上面 POST请求参数是在请求体里面&#xff…

电阻的妙用:限流、分压、滤波,助力电路设计!

电阻可以降低电压&#xff0c;这是通过电阻的分压来实现的。事实上&#xff0c;利用电阻来降低电压只是电阻的多种功能之一。电路中的电阻与其他元件&#xff08;电容、电感&#xff09;结合用于限流、滤波等。&#xff08;本文素材来源&#xff1a;https://www.icdhs.com/news…

七段码(蓝桥杯)

文章目录 七段码题目描述答案&#xff1a;80分析编程求解&#xff1a;有多种方法方法一&#xff1a;状态压缩枚举构图&#xff08;以二极管为顶点&#xff09;DFS判断连通代码方法二&#xff1a;bfs 七段码 题目描述 小蓝要用七段码数码管来表示一种特殊的文字。 上图给出了…

win11 环境配置 之 Jmeter

一、安装 JDK 1. 安装 jdk 截至当前最新时间&#xff1a; 2024.3.27 jdk最新的版本 是 官网下载地址&#xff1a; https://www.oracle.com/java/technologies/downloads/ 建议下载 jdk17 另存为到该电脑的 D 盘下&#xff0c;新建jdk文件夹 开始安装到 jdk 文件夹下 2. 配…

自动化测试框架Taffy

Taffy Taffy是基于nosetests的自动化测试框架。 Taffy主要用来测试后台服务(包括且不限于Http, Dubbo/hessian, Webservice, Socket等类型接口)&#xff0c;也可集成Selenium, Appium进行WEB或APP的自动化测试&#xff0c;或集成locust进行性能测试。 Taffy封装实现了结果对…