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.//位掩码是0x11uxBits = 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.mzph.cn/news/722462.shtml

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

相关文章

SQL技巧笔记(一):连续3人的连号问题—— LeetCode601.体育馆的人流量

SQL 技巧笔记 前言&#xff1a;我发现大数据招聘岗位上的应聘流程都是需要先进行笔试&#xff0c;其中占比很大的部分是SQL题目&#xff0c;经过一段时间的学习之后&#xff0c;今天开了一个力扣年会员&#xff0c;我觉得我很有必要去多练习笔试题目&#xff0c;这些题目是有技…

Linux - 进程概念

1、冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系&#xff1b; 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成&#xff1a; 输入单元&#xff1a;…

【JavaEE】_Spring MVC项目使用数组与集合传参

目录 1. 使用数组传参 1.2 传递单个参数 1.3 传递多个名称相同的参数 1.3.1 关于urlencode 2. 使用集合传参 1. 使用数组传参 创建一个Spring MVC项目&#xff0c;其中 .java文件内容如下&#xff1a; package com.example.demo.controller;import com.example.demo.Per…

自我对比: 通过不一致的解决视角更好地进行反思

一、写作动机&#xff1a; LLM 在自我评价时往往过于自信或随意性较大&#xff0c;提供的反馈固执或不一致&#xff0c;从而导致反思效果不佳。为了解决这个问题&#xff0c;作者提倡 "自我对比"&#xff1a; 它可以根据要求探索不同的解决角度&#xff0c;对比差异…

周边类-找厕所小程序源码

源码获取方式 1&#xff0c;搜一搜 万能工具箱合集 点击资料库 即可进去获取 找厕所小程序源码依赖于腾讯地图的一款源码&#xff0c;腾讯地图api免费申请&#xff0c;是一款免费又永久的不需要服务器的小程序&#xff0c;起个好名字蹭蹭蹭~ 搭建教程&#xff1a; 1、下载源码…

使用css的transition属性实现抽屉功能

需求 使用css手写一个抽屉&#xff0c;并且不能遮挡住原来的页面 效果&#xff1a;&#xff08;录的gif有点卡&#xff0c;实际情况很丝滑&#xff09; 实现代码&#xff1a; <template><div class"dashboard-container"><div class"mainBox&…

Java项目:36 springboot图书个性化推荐系统的设计与实现003

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 springboot003图书个性化推荐系统的设计与实现 管理员&#xff1a;首页、个人中心、学生管理、图书分类管理、图书信息管理、图书预约管理、退…

[element]element-ui框架下载

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐如果觉得文章写的不错&#xff0c;欢迎点个关注一键三连&#x1f609;有写的不好的地方也欢迎指正&#xff0c;一同进步&#x1f601;…

基于Springboot的足球俱乐部管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的足球俱乐部管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍: 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff…

【Datawhale组队学习:Sora原理与技术实战】Attention和LLM

Attention Attention 注意力&#xff0c;从两个不同的主体开始。 论文&#xff1a;https://arxiv.org/pdf/1703.03906.pdf seq2seq代码仓&#xff1a;https://github.com/google/seq2seq 计算方法&#xff1a; 加性Attention&#xff0c;如&#xff08;Bahdanau attention&…

数据库-ODBC操作

承接Qt/C软件开发项目&#xff0c;高质量交付&#xff0c;灵活沟通&#xff0c;长期维护支持。需求所寻&#xff0c;技术正适&#xff0c;共创完美&#xff0c;欢迎私信联系&#xff01; 一、ODBC 数据源配置 打开ODBC数据源管理器&#xff1a; 在Windows搜索栏中键入“ODBC数…

PyTorch搭建LeNet神经网络

函数的参数 1、PyTorch Tensor的通道排序 [batch, channel, height, width] batch: 要处理的一批图像的个数 channel: 通道数&#xff08;一般是R G B 三个通道&#xff09; height: 图像的高度 width: 图像的宽度 2.Conv 2d 卷积层的参数 [in_channels, out_channels, ke…

Golang 开发实战day01 - Variable String Numeric

Golang 教程01 - Variable String Numeric 1. Go语言的重要性 Go语言&#xff0c;又称Golang&#xff0c;是一种由Google开发的静态编译型编程语言。它于2009年首次发布&#xff0c;并在短短几年内迅速流行起来。Go语言具有以下特点&#xff1a; 语法简单易学&#xff1a;Go…

第一节 JDBC是什么?

JDBC代表Java数据库连接(Java Database Connectivity)&#xff0c;它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API&#xff0c;换句话说&#xff1a;JDBC是用于在Java语言编程中与数据库连接的API。 JDBC库包括通常与数据库使用相关&#xff0c;如下面提到的…

链表哨兵例子

哨兵链表例子_根据值删除链表 package linklist;public class leetcode203 {public static void main(String[] args) {ListNode listNode new ListNode(1,new ListNode(2,new ListNode(3)));ListNode listNode1 removeElements(listNode,2);System.out.println(listNode1);…

LeetCode.232. 用栈实现队列

题目 232. 用栈实现队列 分析 先了解一下栈和队列的特点&#xff1a; 栈&#xff1a;先进后出队列&#xff1a;先进先出 想用栈实现队列的特点&#xff0c;就需要使用两个栈。因为两个栈就可以将列表倒序。 假设第一个栈 s1 [1,2,3]&#xff0c;第二个栈 s2 [] 。若循环…

STM32FreeRTOS消息队列(STM32Cube高效开发)

文章目录 一、队列&#xff08;一&#xff09;简介&#xff08;二&#xff09;FreeRTOS队列特点1、入队阻塞&#xff1a;队列满了&#xff0c;此时无法继续写入数据2、出队阻塞&#xff1a;队列为空&#xff0c;此时无法读出数据3、入队阻塞解除&#xff0c;有多个任务等待时&a…

【李沐论文精读】GAN精读

论文&#xff1a;Generative adversarial nets 参考&#xff1a;GAN论文逐段精读、生成对抗网络、李沐视频精读系列 一、介绍 什么是GAN? GAN(Generative adversarial network&#xff0c;生成对抗网络&#xff09;&#xff0c;它由生成器G&#xff08;Generator Neural Netwo…

如何把已安装的nodejs高版本降级为低版本

第一步.先清空本地安装的node.js版本 按健winR弹出窗口&#xff0c;键盘输入cmd,然后敲回车&#xff08;或者鼠标直接点击电脑桌面最左下角的win窗口图标弹出&#xff0c;输入cmd再点击回车键&#xff09; 然后进入命令控制行窗口&#xff0c;并输入where node查看之前本地安装…

android开发游戏加速器,Android架构组件Room功能详解

Java基础 Java Object类方法HashMap原理&#xff0c;Hash冲突&#xff0c;并发集合&#xff0c;线程安全集合及实现原理HashMap 和 HashTable 区别HashCode 作用&#xff0c;如何重载hashCode方法ArrayList与LinkList区别与联系GC机制Java反射机制&#xff0c;Java代理模式Jav…