FreeRTOS——事件标志组

一、事件标志组

        前面所介绍的队列、信号量,只能实现与单个任务进行同步。而有时候某个任务可能需要与多个事件或任务进行同步,此时,事件标志组的作用就凸显出来

1.1 事件标志组简介

事件标志位:用一个位,来表示事件是否发生

事件标志组:一组事件标志位的集合, 可以简单的理解事件标志组,就是一个(16/32)整数

事件标志组是一种实现任务/中断间通信的机制,主要用于实现多任务间的同步

根据configUSE_16_BIT_TICKS 的宏定义不同,每个事件标志组的位数也就不同

        虽然使用了 32 位无符号的数据类型变量来存储事件标志, 但其中的8用作存储事件标志组的控制信息,低24位用作存储事件标志 ,所以说一个事件组最多可以存储 24 个事件标志

        可以发现,事件标志组与外设的状态寄存器SR非常类似,每一位都代表一个事件是否发生(高8位除外) 

1.2 事件标志组与队列、信号量的区别

此外:设置事件不会阻塞等待事件标志支持阻塞 

 

二、事件组结构体

typedef struct EventGroupDef_t
{EventBits_t uxEventBits;List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t uxEventGroupNumber;#endif/* 如果事件组是静态分配,则设置为pdTURE,以确保不尝试释放内存 */#if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */#endif
} EventGroup_t;
成员说明
uxEventBits

EventBits_t类型的变量,其中,

高八位:事件标志组的控制信息

剩余位:存储事件标志(1:发生;2:未发生)

xTasksWaitingForBits链表,等待事件标志位的任务的链表

三、相关API

函数

描述

xEventGroupCreate()

使用动态方式创建事件标志组

xEventGroupCreateStatic()

使用静态方式创建事件标志组

xEventGroupClearBits()

清零事件标志位

xEventGroupClearBitsFromISR()

在中断中清零事件标志位

xEventGroupSetBits()

设置事件标志位

xEventGroupSetBitsFromISR()

在中断中设置事件标志位

xEventGroupWaitBits()

等待事件标志位

xEventGroupSync()

设置事件标志位,并等待事件标志位

2.1 动态创建事件组

使用条件:configSUPPORT_DYNAMIC_ALLOCATION必须在 FreeRTOSConfig.h 中设置为 1,或保留未定义状态(此时默认为 1)

EventGroupHandle_t    xEventGroupCreate ( void ) ; 

返回值

描述

NULL

事件标志组创建失败

句柄

事件标志组创建成功

2.1.1 函数详解


#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )EventGroupHandle_t xEventGroupCreate( void ){/* 创建一个事件标志组结构体指针:pxEventBits */EventGroup_t * pxEventBits;/* 申请结构体空间,并将首地址赋给指针变量:pxEventBits */pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /* 申请成功 */if( pxEventBits != NULL ){/* 将结构体中的时间标志组变量初始化为0*/pxEventBits->uxEventBits = 0;/* 初始化等待任务链表 */vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );#if ( configSUPPORT_STATIC_ALLOCATION == 1 ){pxEventBits->ucStaticallyAllocated = pdFALSE;}#endif /* configSUPPORT_STATIC_ALLOCATION */traceEVENT_GROUP_CREATE( pxEventBits );}/* 申请失败 */else{traceEVENT_GROUP_CREATE_FAILED(); }/* 返回结构体的地址 */return pxEventBits;}

 2.1.2 函数实现总结

(1)创建一个时间标志组的结构体指针变量

(2)申请内存空间

        成功:将事件标志组变量初始化为0,并初始化等待事件标志任务列表

        失败:定义但未实现的宏

(3)返回:事件标志组的结构体指针变量

2.2 清除事件标志位

EventBits_t  xEventGroupClearBits( EventGroupHandle_t 	xEventGroup,				                                  const EventBits_t 	uxBitsToClear ) 

形参

描述

xEventGroup

待操作的事件标志组句柄

uxBitsToSet

待清零的事件标志位

返回值

描述

整数

清零事件标志位之前事件组中事件标志位的值

注:要清零的事件标志位,可以是一位,也可以是多位

0x08: 清除bit3

0x09:清除bit3和bit0

 2.3 设置事件标志位

EventBits_t   xEventGroupSetBits(  EventGroupHandle_t 	xEventGroup,					  const EventBits_t 		uxBitsToSet    ) 

形参

描述

xEventGroup

待操作的事件标志组句柄

uxBitsToSet

待设置的事件标志位 

返回值

描述

整数

函数返回时,事件组中的事件标志位值

注:要设置的事件标志位,可以是一位,也可以是多位

0x08: 设置bit3

0x09:设置bit3和bit0

2.4 获取事件标志组值

 

2.5 等待事件标志位

等待事件标志组的某些位被设置,选择性的进入阻塞状态,中断中无法调用此函数

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

形参

描述

xEvenrGroup

等待的事件标志组句柄

uxBitsToWaitFor

等待的事件标志位,可以用逻辑或等待多个事件标志位

xClearOnExit

成功等待到事件标志位后,清除事件组中对应的事件标志位,

                pdTRUE  :清除uxBitsToWaitFor指定位;

                pdFALSE:不清除

xWaitForAllBits

等待 uxBitsToWaitFor 中的所有事件标志位(逻辑与)

pdTRUE:等待的位,全部为1     逻辑与

pdFALSE:等待的位,某个为1   逻辑或

xTicksToWait

等待的阻塞时间

返回值

描述

等待的事件标志位值

等待事件标志位成功,返回所等待到的事件标志位置1的事件标志组的值

其他值

等待事件标志位失败,返回事件组中的事件标志位

2.4.1 函数详解

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToWaitFor,const BaseType_t xClearOnExit,const BaseType_t xWaitForAllBits,TickType_t xTicksToWait )
{/*** uxReturn:返回值(32位时间标志组变量)* uxControlBits:记录控制位信息(高八位)* xWaitConditionMet:记录等待条件是否已满足* xAlreadyYielded:记录调度器的状态*/EventGroup_t * pxEventBits = xEventGroup;EventBits_t uxReturn, uxControlBits = 0;BaseType_t xWaitConditionMet, xAlreadyYielded;BaseType_t xTimeoutOccurred = pdFALSE;/* 检查用户没有去尝试等待内核本身使用的位(高8位),并且至少请求了一个位(低24位)。*/configASSERT( xEventGroup );configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );configASSERT( uxBitsToWaitFor != 0 );#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ){configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );}#endif/* 挂起调度器 */vTaskSuspendAll();{/* 取出结构体的32位变量,赋值给uxCurrentEventBitsconst EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;/* 检查是否以满足等待条件 */xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );/* 等待条件已满足 */if( xWaitConditionMet != pdFALSE ){/* 将32变量赋给uxReturn,并将等待时间设置为0 */uxReturn = uxCurrentEventBits;xTicksToWait = ( TickType_t ) 0;/* 判断是否需要清除标志位 */if( xClearOnExit != pdFALSE ){pxEventBits->uxEventBits &= ~uxBitsToWaitFor;}else{mtCOVERAGE_TEST_MARKER();}}/* 等待条件不满足,并且未设置等待时间 */else if( xTicksToWait == ( TickType_t ) 0 ){/* 返回当前32位变量,并将超时标志置为:pdTURE */uxReturn = uxCurrentEventBits;xTimeoutOccurred = pdTRUE;}/* 等待条件不满足 */else{/* 需要清除标志位,将第25位置1 */if( xClearOnExit != pdFALSE ){uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;}else{mtCOVERAGE_TEST_MARKER();}/* 需要等待所有标志位 or 至少一个标志位,将第26位置1 */if( xWaitForAllBits != pdFALSE ){uxControlBits |= eventWAIT_FOR_ALL_BITS;}else{mtCOVERAGE_TEST_MARKER();}/* 此函数的功能:** (1)控制位 | 等待的事件标志位 的结果,赋给列表项的值(用于升序排列)** (2)将任务添加到等待事件组的列表中** (3)将任务添加到阻塞列表中,任务进入阻塞状态*/vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );/* 返回值赋为0 */uxReturn = 0;traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );}}/* 恢复调度器 */xAlreadyYielded = xTaskResumeAll();if( xTicksToWait != ( TickType_t ) 0 ){if( xAlreadyYielded == pdFALSE ){portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}/* The task blocked to wait for its required bits to be set - at this* point either the required bits were set or the block time expired.  If* the required bits were set they will have been stored in the task's* event list item, and they should now be retrieved then cleared. */uxReturn = uxTaskResetEventItemValue();if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ){taskENTER_CRITICAL();{/* The task timed out, just return the current event bit value. */uxReturn = pxEventBits->uxEventBits;/* It is possible that the event bits were updated between this* task leaving the Blocked state and running again. */if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ){if( xClearOnExit != pdFALSE ){pxEventBits->uxEventBits &= ~uxBitsToWaitFor;}else{mtCOVERAGE_TEST_MARKER();}}else{mtCOVERAGE_TEST_MARKER();}xTimeoutOccurred = pdTRUE;}taskEXIT_CRITICAL();}else{/* The task unblocked because the bits were set. */}/* The task blocked so control bits may have been set. */uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;}traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );/* Prevent compiler warnings when trace macros are not used. */( void ) xTimeoutOccurred;return uxReturn;
}

2.6 同步函数

EventBits_t    xEventGroupSync(   EventGroupHandle_t 	xEventGroup,						 const EventBits_t 	uxBitsToSet,					const EventBits_t 	uxBitsToWaitFor,					TickType_t 		xTicksToWait) 

形参

描述

xEventGroup

等待事件标志所在事件组

uxBitsToSet

达到同步点后,要设置的事件标志

uxBitsToWaitFor

等待的事件标志

xTicksToWait

等待的阻塞时间,等待uxBitsToWaitFor参数值指定的 所有位设置完成的最长时间 

返回值

描述

等待的事件标志位值

等待事件标志位成功,返回等待到的事件标志位

其他值

等待事件标志位失败,返回事件组中的事件标志位

特点:通过设置某一位或多位(uxBitsToSet) ,等待标志位(uxBitsToWaitFor),即设置了uxBitsToSet,还需要等待uxBitsToWaitFor被设置才可以进行后续操作

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

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

相关文章

二、Spring

二、Spring 1、Spring简介 1.1、Spring概述 官网地址&#xff1a;https://spring.io/ Spring 是最受欢迎的企业级 Java 应用程序开发框架&#xff0c;数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。 Spring 框架是一个开源的 Jav…

密码学及其应用 —— 密码学的经典问题

1. 古典密码学问题 1.1 问题1&#xff1a;破解凯撒密码 1.1.1 问题 凯撒密码是最简单的单字母替换加密方案。这是一种通过将字母表中的字母固定向右移动几位来实现的加密方法。解密下面的文本&#xff0c;该文本通过对一个去除了空格的法语文本应用凯撒密码获得&#xff1a; …

ruoyi mybatis pagehelper 分页优化(自定义limit位置)clickhouse 外部数据源

例如加入clickhouse的分页时发现extends 不生效 则可以添加 startPage();registerDialectAlias("clickhouse", PageMySqlDialectPlus.class);List<MyMonitorlog> list monitorlogService.selectMonitorlogList(monitorlog);主要是需要注册 registerDialectAl…

js获取当前浏览器地址,ip,端口号等等

前言&#xff1a; js获取当前浏览器地址&#xff0c;ip&#xff0c;端口号等等 window.location属性查询 具体属性&#xff1a; 1、获取他的ip地址 window.location.hostname 2、获取他的端口号 window.location.port 3、获取他的全路径 window.location.origin 4、获取…

认识异常详解

1. 异常的定义&#xff1a; 在Java中&#xff0c;异常&#xff08;Exception&#xff09;是在程序执行过程中可能出现的错误或意外情况。异常可以分为两种类型&#xff1a;受检异常&#xff08;Checked Exception&#xff09;和未受检异常&#xff08;Unchecked Exception&…

【linux学习---1】点亮一个LED是多么的困难!!!

文章目录 1、原理图找对应引脚2、IO复用3、IO配置4、GPIO配置5、GPIO时钟使能6、总结7、编程8、编译9、链接10、格式转换11、反汇编&#xff08;查看用&#xff09;12、使用Makefile操作13、代码烧写14、代码验证 1、原理图找对应引脚 从上图 可以看出&#xff0c; 蜂鸣器 接到…

固态,机械,移动(U盘),sd卡,哪个更适合长期储存数据 保存数据用什么硬盘可靠 硬盘数据丢失怎么找回 硬盘维护注意事项

有关硬盘数据丢失的恢复技巧&#xff0c;这篇文章一定要收藏好。在硬盘使用过程中&#xff0c;很多情况都会导致数据丢失&#xff0c;例如硬盘跌落、病毒感染、系统文件损坏等。这时候&#xff0c;一定要采用正确的方法&#xff0c;抢救硬盘中存储的珍贵数据和文档。 有关长期保…

PO模式简介

V1顺序型&#xff1a;不能批量运行 import unittest from selenium import webdriver from time import sleep driver webdriver.Edge()# driver.maximize_window() driver.implicitly_wait(30) # driver.get(r"https://demo5.tp-shop.cn/") # driver.find_element…

Python 获取tiktok视频评论回复数据 api接口

TIKTOK api接口 用于爬取tiktok视频评论回复数据 详细采集页面如图 https://www.tiktok.com/dailymail/video/7329872821990182190?qneural%20link&t1706783508149 请求API http://api.xxxx.com/tt/video/info/comment/reply?video_id7288909913185701125&comment_…

【C++】指针的点运算与箭头运算(->)的奥秘与应用

在编程的世界里&#xff0c;指针作为连接程序与内存之间的桥梁&#xff0c;扮演着至关重要的角色。对于使用C、C等语言进行开发的程序员而言&#xff0c;理解并掌握指针的使用技巧是提升编程能力的必经之路。其中&#xff0c;指针的点运算&#xff08;.&#xff09;和箭头运算&…

Android系统集成和使用FFmpeg

文章目录 前言FFmpeg源码下载交叉编译NDK下载x264编译源码下载编译 FFmpeg编译脚本 AOSP继承FFmpeg 前言 原生AOSP中并未继承FFmpeg&#xff0c;所以要想在android上使用&#xff0c;需要自己编译集成。 FFmpeg源码下载 git clone https://git.ffmpeg.org/ffmpeg.git目前最新…

自动化测试报告pytest-html样式美化

最近我将 pytest-html 样式优化了 一版 先看优化前&#xff1a; 优化后&#xff1a; 优化内容包括&#xff1a; 删除部分多余字段新增echart图表部分字体大小、行间距、颜色做了美化调整运行环境信息移至报告最后部分字段做了汉化处理&#xff08;没全部翻译是因为&#xf…

vue3 引入百度地图的三种方式

本次也是正好写了一个基于VUE3和百度地图的设计&#xff0c;但奈何第一次使用百度地图&#xff0c;在学习的途中遇到了很多问题&#xff0c;也发现网上的材料相对较少&#xff0c;因此做出了一些小总结&#xff0c;后续还会更新。 一、直接引入 直接在public中的index.html中进…

[FreeRTOS 功能应用] 事件组 功能应用

文章目录 一、基础知识点二、代码讲解三、结果演示四、代码下载 一、基础知识点 [FreeRTOS 基础知识] 事件组 概念 [FreeRTOS 内部实现] 事件组 本实验是基于STM32F103开发移植FreeRTOS实时操作系统&#xff0c;事件组实战操作。(当task1和task2同时完成&#xff0c;才执行ta…

二维Gamma分布的激光点云去噪

目录 1、Gamma 分布简介2、实现步骤 1、Gamma 分布简介 Gamma 分布在合成孔径雷达( Synthetic Aperture &#xff32;adar&#xff0c;SA&#xff32;) 图像分割中具有广泛应用&#xff0c;较好的解决了SA&#xff32; 图像中相干斑噪声对图像分割的影响。采用二维Gamma 分布对…

web前端开发——开发环境和基本知识

今天我来针对web前端开发讲解一些开发环境和基本知识 什么是前端 前端通常指的是网站或者Web应用中用户可以直接与之交互的部分&#xff0c;包括网站的结构、设计、内容和功能。它是软件开发中的一个专业术语&#xff0c;特别是指Web开发领域。前端开发涉及的主要技术包括HTML…

昇思25天学习打卡营第15天|linchenfengxue

Pix2Pix实现图像转换 Pix2Pix概述 Pix2Pix是基于条件生成对抗网络&#xff08;cGAN, Condition Generative Adversarial Networks &#xff09;实现的一种深度学习图像转换模型&#xff0c;该模型是由Phillip Isola等作者在2017年CVPR上提出的&#xff0c;可以实现语义/标签到…

Java常用算法集合扩容机制分析

基础篇 基础篇要点&#xff1a;算法、数据结构、基础设计模式 1. 二分查找 要求 能够用自己语言描述二分查找算法能够手写二分查找代码能够解答一些变化后的考法 算法描述 前提&#xff1a;有已排序数组 A&#xff08;假设已经做好&#xff09; 定义左边界 L、右边界 R&…

东芝TB6560AHQ/AFG步进电机驱动IC:解锁卓越的电机控制性能

作为一名工程师&#xff0c;一直在寻找可靠且高效的组件来应用于你的项目中。东芝的TB6560AHQ/AFG步进电机驱动IC能够提供精准且多功能的电机控制&#xff0c;完全符合现代应用的高要求&#xff0c;保证高性能和易用性。在这篇文章中&#xff0c;我们将探讨TB6560AHQ/AFG的主要…

硅纪元视角 | 国内首款鸿蒙人形机器人“夸父”开启应用新篇章

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…