STM32FreeRTOS-事件组1(STM32Cube高效开发教程)

文章目录

  • 一、事件组的原理和功能
    • 1、事件组与队列信号量特点
    • 2、事件组存储结构
    • 3、事件组运行原理
  • 二、事件组部分函数
    • 1、xEventGroupCreate()创建事件组函数
    • 2、xEventGroupSetBits()事件组置位函数
    • 3、xEventGroupSetBitsFromISR()事件组置位函数ISR版本
    • 4、xEventGroupClearBits()事件位清零函数
    • 5、xEventGroupClearBitsFromISR()事件位清零函数ISR版本
    • 6、xEventGroupGetBits()读取事件组当前的值
    • 7、xEventGroupWaitBits()等待事件组成立

一、事件组的原理和功能

1、事件组与队列信号量特点

事件组是FreeRTOS中的一种对象,且FreeRTOS默认就可以使用事件组,无需设置相关参数,但是使用之前需要使用创建函数创建事件组对象。
在这里插入图片描述
事件标志组与队列信号量的区别:
在这里插入图片描述

2、事件组存储结构

事件组有一个内部变量存储事件标志,当configUSE_16_BIT_TICKS为0时,这个变量是32位的,否则是16位的,在STM32上处理器上是32位的。

使用了32位无符号的数据类型变量来存储事件标志,但其中的高8位用作存储事件标志组的控制信息,低24位用作存储事件标志,所以说一个事件组最多可以存储 24 个事件标志!
在这里插入图片描述

一个事件组中的所有事件位保存在一个EventBits_t类型的变量里,所以一个事件又称为一个“事件位”
在这里插入图片描述

3、事件组运行原理

在这里插入图片描述

(1)设置事件组中的位与某个事件对应,检测到事件发生时将相应的位置1,表示事件发生了。
(2)可以有1个或多个任务等待事件组中的事件发生,可以是各个事件都发生(事件位的与运算),或某个事件发生(事件位的或运算)。
(3)假设图中的Task1和Task2都以阻塞状态等待两个事件都发生,当Bit2和Bit0都被置为1后(不分先后顺序),两个任务都会被解除阻塞状态。所以 事件组具有广播功能。
在这里插入图片描述

二、事件组部分函数

函数所在文件如下图所示:
在这里插入图片描述

1、xEventGroupCreate()创建事件组函数

以动态分配内存方式创建事件组,无参数,返回值是创建的事件组句柄变量(一个指针变量),其他函数在操作事件组时都使用事件组句柄变量作为输入参数。
在这里插入图片描述
返回值类型EventGroupHandle_t的定义如下:
在这里插入图片描述
在这里插入图片描述

2、xEventGroupSetBits()事件组置位函数

在这里插入图片描述

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;

参数1:要操作的事件组句柄
参数2:要置位的事件位掩码
返回值:置位成功后事件组当前的值

类型EventBits_t的定义如下,也就是TickType_t,在STM32处理器上,等同于类型uint32_t

被置位的事件位为1,未被置位的事件位为0,一个事件只对应事件组中的一个事件位,一个事件发生只需要置位一个事件位
在这里插入图片描述

需要置位事件组中的bit7,则位掩码是0x80
需要置位事件组中的bit0,则位掩码是0x01
同时置位事件组中的bit7和bit0,则位掩码是0x81
官方代码段举例:

Example usage:

	//想要置位哪一个事件位通过宏定义操作即可
   #define BIT_0	( 1 << 0 ) //宏定义:置位bit0对应的事件位
   #define BIT_4	( 1 << 4 ) //宏定义:置位bit4对应的事件位


   void aFunction( EventGroupHandle_t xEventGroup )
   {
  		 EventBits_t uxBits; //存放置位函数返回值

		//使用时间位0和事件位4进行置位操作
		//对两个事件位的宏定义进行或操作,就是同时对两个位进行置位(也就是传递的参数2位掩码)
	
		// Set bit 0 and bit 4 in xEventGroup.
		//位掩码是0x11
		uxBits = xEventGroupSetBits(
							xEventGroup,	// The event group being updated.
							BIT_0 | BIT_4 );// The bits being set.
			

		//函数返回值是置位成功后事件组当前的数值
			
		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )//bit0和bit4同时被置位	
		{
			// Both bit 0 and bit 4 remained set when the function returned.
		}
		
		else if( ( uxBits & BIT_0 ) != 0 )//bit0被置位
		{
			// Bit 0 remained set when the function returned, but bit 4 was
			// cleared.  It might be that bit 4 was cleared automatically as a
			// task that was waiting for bit 4 was removed from the Blocked
			// state.
		}
		else if( ( uxBits & BIT_4 ) != 0 )//bit4被置位
		{
			// Bit 4 remained set when the function returned, but bit 0 was
			// cleared.  It might be that bit 0 was cleared automatically as a
			// task that was waiting for bit 0 was removed from the Blocked
			// state.
		}
		else//bit0和bit4均没有被置位
		{
			// Neither bit 0 nor bit 4 remained set.  It might be that a task
			// was waiting for both of the bits to be set, and the bits were
			// cleared as the task left the Blocked state.
		}
   }

3、xEventGroupSetBitsFromISR()事件组置位函数ISR版本

ISR版本相对于任务版本多了最后一个参数:是否需要进行上下文切换的申请
根据参数configUSE_TRACE_FACILITY数值为1或0分为以下两个版本

#if( configUSE_TRACE_FACILITY == 1 )
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
#else
	#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
#endif

默认的函数原型:
pxHigherPriorityTaskWoken是指针BaseType_t*,是一个返回值(pdTRUE或pdFALSE),表示在退出ISR函数前是否需要申请进行一次任务调度。

BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
									const EventBits_t uxBitsToSet, 
									BaseType_t *pxHigherPriorityTaskWoken );
/*
参数1:事件组句柄
参数2:置位掩码
参数3:退出ISR时是否需要上下文切换
*/
//示意代码如下:
BaseType_t highTaskWoken =pdFALSE;
xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, &highTaskWoken);
portYIELD_FROM_ISR(highTaskWoken); //申请进行一次任务调度

Freeertos不允许中断或临界代码段进行不确定的操作,在ISR中进行事件组置位操作时FreeRTOS实际上向定时器守护任务发送了一个消息,将事件组置位操作延后到定时器守护任务里执行。
如果定时器优先值高于当前执行的任务,返回pdtrue,否则返回pdfalse
根据pdtrue手动的进行一次上下文切换,这个函数返回pdtrue表明延后处理的消息成功的发送给了定时器守护任务,当定时器守护任务的队列消息满时,函数会无法接收到新的消息,返回值为pdfalse

4、xEventGroupClearBits()事件位清零函数

函数xEventGroupClearBits()用于在任务函数中将事件组的某些事件位清零,其函数原型是

EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, 
								const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;


参数1:事件组句柄
参数2:要清零的事件位掩码(掩码意义与事件位置位中一样)
返回值:事件位被清零之前的事件组的值

uxBitsToClear是需要清零的事件位的掩码, 需要清零的位设置为1。
将bit0和bit4清零
在这里插入图片描述

5、xEventGroupClearBitsFromISR()事件位清零函数ISR版本

#if( configUSE_TRACE_FACILITY == 1 )
	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
#else
	#define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL )
#endif

在ISR函数中的事件位清零操作会被延后到定时器守护任务(timer daemon task) 中去处理,函数的返回值为pdTRUE或pdFALSE,如果返回值为pdTRUE表示延后处理的消息成功发送给了定时器守护任务,否则就是没有成功发送。

6、xEventGroupGetBits()读取事件组当前的值

传入事件组句柄(不清空任何位)
在这里插入图片描述

它实际上就是执行了函数xEventGroupClearBits(),只是传递的事件位掩码是0,也就是不清除任何事件位,而返回事件组当前的值
在这里插入图片描述

7、xEventGroupWaitBits()等待事件组成立

函数xEventGroupWaitBits()使当前任务进入阻塞状态,以等待事件组中多个事件位表示的事件成立时再退出阻塞状态。
事件组成立的条件可以是多个事件位都被置位(逻辑与运算) ,或其中某个事件位被置位(逻辑或运算)

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, 
									const EventBits_t uxBitsToWaitFor, 
									const BaseType_t xClearOnExit, 
									const BaseType_t xWaitForAllBits,
									 TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

/*
参数1:事件组句柄
参数2:所等待事件位的掩码(如果需要等待某个事件位置1,掩码中相应的位就设置为1)
参数3:设定值为pdTRUE或pdFALSE,退出时是否清除掩码位(清零)
	pdTRUE则表明在事件组条件成立退出阻塞状态时,会将参数2掩码中指定的所有位全部清零
	如果函数因为超时退出阻塞状态,即使设置为pdTRUE也不会将掩码事件位清零
参数4:设定值为pdTRUE或pdFALSE,是否等待所有位置位(所有同时成立还是某一个成立即可)
	pdTRUE表示事件位全部置1条件成立(逻辑与运算),否则任意一个置1条件成立(逻辑或运算)
	当事件条件成立时,函数就会退出,任务退出阻塞态
参数5:超时阻塞时间

返回值:
*/

在这里插入图片描述

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

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

相关文章

Geeker Admin添加若以分离版本的后台作为后台

添加验证码 下载若依赖前后端分离版本&#xff0c;配置好自己数据库&#xff0c;redis连接地址 登录添加验证码 配置自己的若依后端连接地址 添加验证码请求方法 登录页面登录输入框添加验证码&#xff0c;uuid,调用的验证码刷新方法 注意&#xff1a;这里要用响应式定义验证…

外汇天眼:蓝莓市场终止所有MT4/MT5专业公司业务

总部位于澳大利亚的零售外汇和差价合约经纪商蓝莓市场宣布&#xff0c;已终止其数据和平台服务产品&#xff0c;该产品旨在通过利用其基础设施为专业公司行业提供服务。 蓝莓市场表示&#xff0c;已经对其数据和平台服务产品“落下帷幕”&#xff0c;与所有专业交易公司包括MyF…

分类问题经典算法 | 二分类问题 | Logistic回归:梯度下降

目录 一. 损失函数1. 交叉熵损失函数2. 梯度下降 一. 损失函数 Logistic回归算法公式推导篇中&#xff0c;我们通过对似然函数求对数&#xff0c;得到 l ( θ ) l(\theta ) l(θ)&#xff1a; l ( θ ) l n [ L ( θ ) ] ∑ i 1 M { y ( i ) l n [ h θ ( x ( i ) ) ] ( …

Jekins 自启动Java应用的Shell笔记

背景 最近在研究jdk 的jvisualvm 对JVM服务远程监控时&#xff0c;意外的与jekins接轨了。公司使用jekins自动从Git上获得源码&#xff0c;打包后传到测试服务器并启动jar包&#xff0c;实现自动部署&#xff0c;而我需要做的是在测试服务器启动jar包时添加几个我设置的命令&am…

【YOLO v5 v7 v8 v9小目标改进】DWRSeg:优化的多尺度处理,传统的深度学习模型可能在不同尺度的特征提取上存在冗余

DWRSeg&#xff1a;优化的多尺度处理&#xff0c;传统的深度学习模型可能在不同尺度的特征提取上存在冗余 提出背景问题&#xff1a;实时语义分割需要快速且准确地处理图像数据&#xff0c;提取出有意义的特征来识别不同的对象。 小目标涨点YOLO v5 魔改YOLO v7 魔改YOLO v8 魔…

超级副业SOP,各行各业,太全了!

最近收集到一份资料&#xff0c;包含了几乎各行各业的SOP&#xff0c;实在是太全了&#xff0c;这里准备分享给大家 这里可能有一些朋友还不知道&#xff0c;SOP是个什么东西呢 百度说法&#xff1a;所谓SOP&#xff0c;是 Standard Operating Procedure三个单词中首字母的大写…

【亲测】注册Claude3教程:解决无法发送手机验证码的问题

Anthropic 今日宣布推出其最新大型语言模型&#xff08;LLM&#xff09;系列——Claude 3&#xff0c;这一系列模型在各种认知任务上树立了新的性能标准。Claude 3 系列包括三个子模型&#xff1a;Claude 3 Haiku、Claude 3 Sonnet 和 Claude 3 Opus&#xff0c;每个模型都提供…

MATLAB读取.nc(数据集)文件

MATLAB读取.nc(数据集)文件 以中国1km逐月潜在蒸散发数据集&#xff08;1901-2022&#xff09;为例 首先用FileZilla下载特定年份的数据集 用matlab进行处理&#xff0c;代码如下&#xff1a; clear;clc;ncdisp("pet_2022.nc") %读数据集的具体信息和变量eva ncr…

LABEL-EFFICIENT SEMANTIC SEGMENTATION WITHDIFFUSION MODELS

基于扩散模型的标签高效语义分割 摘要&#xff1a; 去噪扩散概率模型最近受到了很多研究的关注&#xff0c;因为它们优于gan等替代方法&#xff0c;并且目前提供了最先进的生成性能。扩散模型的优越性能使其成为一些应用程序的吸引人的工具&#xff0c;包括绘图&#xff0c;超…

算法学习02:高精度(c++)

算法学习02&#xff1a;高精度&#xff08;c&#xff09; 文章目录 算法学习02&#xff1a;高精度&#xff08;c&#xff09;前言一、高精度1.高 高2.高 - 高3.高 * 低4.高 / 低 总结 前言 提示&#xff1a;以下是本篇文章正文内容&#xff1a; 一、高精度 1.高 高 add函数…

走进亚信安慧AntDB:性能与服务的双优选择

AntDB不仅仅是一个简单的数据库系统&#xff0c;它是一项融合了久经验证、多方位支持和高速处理的综合解决方案。在当今数字化时代&#xff0c;数据驱动着各行各业的发展&#xff0c;而AntDB作为一个全面的数据库解决方案&#xff0c;为用户提供了强大的支持和功能。其独特的设…

Java毕业设计 基于SpringBoot 众筹网

Java毕业设计 基于SpringBoot 众筹网 SpringBoot 众筹网 功能介绍 注册 邮箱验证码 登录 忘记密码 首页 图片轮播 关于我们 项目列表 发布项目 我的添加项目 提交审核 已在募捐 项目详情 项目介绍 项目进展 捐赠列表 评论 新闻列表 发布新闻 新闻详情 评论新闻 联系我们 提交…

7.2.2 用坐标表示平移 教案设计及课堂检测设计

【学习目标】 1&#xff0e;掌握坐标变化和图形平移的关系&#xff0c;能用点的平移规律求点平移后的点的坐标&#xff0e; 2&#xff0e;会按要求画出平移后的图形&#xff0c;并写出顶点的坐标&#xff0e;

网上搞钱的方法你知道几个?盘点3个普通人都可操作的赚钱项目

项目一&#xff0c;微头条 我们可以借助精彩的文章&#xff0c;分享知识、心得和见解&#xff0c;吸引更多的读者关注并获得更多的点赞与评论。关键字的巧妙运用将使你的文章更具吸引力和影响力&#xff0c;同时也会为你带来更多的关注度和阅读量。我们写微头条文章的时候&…

01. Nginx入门-Nginx简介

Web基础知识 Web协议通信原理 Web协议通信过程 浏览器本身是一个客户端&#xff0c;当输入URL后&#xff0c;首先浏览器会请求DNS服务器&#xff0c;通过DNS获取相应的域名对应的IP。通过IP地址找到对应的服务器后&#xff0c;监理TCP连接。等浏览器发送完HTTP Request&…

redis10 应用问题(穿透、击穿、雪崩、分布式锁)

思维草图 缓存穿透 查询不存在的数据&#xff0c;穿透redis缓存&#xff0c;请求直接攻击后端db。 问题 当系统中引入redis缓存后&#xff0c;一个请求进来后&#xff0c;会先从redis缓存中查询&#xff0c;缓存有就直接返回&#xff08;相当于一道隔离闸&#xff0c;保护db…

【打工日常】使用docker部署轻量的运维监控工具

一、Uptime-Kuma介绍 Uptime-Kuma是一个轻量级的自动化运维监控工具&#xff0c;最为引人注目的特点是其出色的监控Dashboard面板。部署简单&#xff0c;工具轻量又强大。而且&#xff0c;Uptime-Kuma是开源免费的&#xff0c;并支持基于Docker的部署方式。它支持网站、容器、数…

【李沐论文精读】Resnet精读

论文地址&#xff1a;Deep Residual Learning for Image Recognition 参考&#xff1a;撑起计算机视觉半边天的ResNet【论文精读】、ResNet论文逐段精读【论文精读】、【李沐论文精读系列】 一、导论 深度神经网络的优点&#xff1a;可以加很多层把网络变得特别深&#xff0c;然…

Java进阶-测试方法

来学习一下软件测试相关的方法&#xff0c;了解一下黑盒测试和白盒测试&#xff0c;以及后面要用到的JUnit单元测试。JUnit单元测试也属于白盒测试&#xff0c;这次内容较少且相对简单。 一、软件测试方法 1、黑盒测试 不需要写代码&#xff0c;给输入值&#xff0c;看程序…

打家劫舍(java版)

&#x1f4d1;前言 本文主要是【动态规划】——打家劫舍(java版)的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一…
最新文章