[FreeRTOS 内部实现] 事件组

文章目录

    • 事件组结构体
    • 创建事件组
    • 事件组等待位
    • 事件组设置位


事件组结构体

// 路径:Source/event_groups.c
typedef struct xEventGroupDefinition
{
	EventBits_t uxEventBits;
	List_t xTasksWaitingForBits;		
} EventGroup_t;

uxEventBits 中的每一位表示某个事件是否发生。 具体事件由程序员来确定,大小为uint32_t。
xTasksWaitingForBits 为等待事件链表。 若某个事件检测到uxEventBits中所需要的位没有置位,就会将自己保存在该链表中等待。


创建事件组

使用 xEventGroupCreate 函数进行事件组创建

EventGroupHandle_t xEventGroupCreate( void )
	// 1、申请事件组结构体 EventGroup_t 空间
	-> pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
	// 2、初始化结构体中uxEventBits 事件位
	-> pxEventBits->uxEventBits = 0;
	// 3、初始化等待事件组链表
	vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );

事件组等待位

使用xEventGroupWaitBits 函数进行事件等待,函数定义如下:

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

第一参数 EventGroupHandle_t xEventGroup :已经申请并且需要操作事件组句柄
第二参数 const EventBits_t uxBitsToWaitFor :等待的位有哪些
第三参数 const BaseType_t xClearOnExit :在退出的时候是否对等待的位进行清除
第四参数 const BaseType_t xWaitForAllBits:等待的位是同时满足还是只要一个成立就满足(等待位是 与的关系 还是 或的关系 )
第五参数 TickType_t xTicksToWait :等待的时间

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
	// 1、关闭调度器,后面有详解
	-> vTaskSuspendAll();	
	{
		// 2、检查等待条件是否已经满足
		const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
		xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
		// 3、等待条件已经满足,所以没有必要阻塞
		if( xWaitConditionMet != pdFALSE )	
		{
			// 4、判断退出前xClearOnExit 是否清零
			if( xClearOnExit != pdFALSE )
				pxEventBits->uxEventBits &= ~uxBitsToWaitFor;		// 清零
		}
		// 判断是否愿意等待
		else if( xTicksToWait == ( TickType_t ) 0 )
			uxReturn = uxCurrentEventBits;		// 不愿意等待,退出
		else
		{
			// 记录标志位
			if( xClearOnExit != pdFALSE )
				uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
			if( xWaitForAllBits != pdFALSE )
				uxControlBits |= eventWAIT_FOR_ALL_BITS;
		}
		// 将调用任务正在等待的比特存储在任务的事件中列表项,以便内核知道何时找到匹配项。然后进入阻塞状态
		vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
			// 把当前任务加入xEventListItem 链表中
			-> 	listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE );	
			-> 	vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) );
			// 把当前任务从就绪链表移到等待链表中
			-> 	prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
	}

vTaskSuspendAll函数 功能是关闭调度器。在之前的队列操作(包含信号量和互斥量操作)中无论是读还是写操作,第一步就是关中断。而在操作事件组的时候第一步却不需要直接关闭中断,只需要关闭调度器,这两者有什么区别呢?

对于队列操作,存在两种情况:
1、多个任务同时操作队列
2、中断 过程中可以对队列进行读写操作
考虑到第一种情况,多任务之间操作队列会相互影响,可以采取关闭调度器来解决,但是不能屏蔽掉中断中对队列的读写操作。如果只关闭调度器的话,中断对队列的操作同样会对正在的任务有影响。因此任务在对队列进行操作时,第一步一定是要关闭中断。

对于事件组操作,只存在任务之间的操作,中断过程中不会对事件组进行操作,因此只需要关闭调度器就可以实现任务之间对事件组操作的互斥。

在这里插入图片描述


事件组设置位

使用xEventGroupSetBits 函数进行事件设置

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
	-> vTaskSuspendAll();	// 关闭调度器
	{
		// 1、设置对应的位
		pxEventBits->uxEventBits |= uxBitsToSet;
		// 2、唤醒所有满足条件的任务
		while( pxListItem != pxListEnd )
		{
			if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
			{
				if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
					xMatchFound = pdTRUE;
				else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
					xMatchFound = pdTRUE;
				// 从链表中移除
				vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
		}
	}

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

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

相关文章

【LeetCode:3101. 交替子数组计数 + 滑动窗口 + 数学公式】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

怎样把自己电脑ip改成动态ip:步骤与解析

在今天的网络世界中,IP地址是计算机与互联网沟通的桥梁。而动态IP地址,作为其中的一种类型,由于其自动分配和管理的特性,为用户提供了更大的便利性和灵活性。那么,您是否想知道怎样将电脑IP改为动态呢?本文…

用Excel处理数据图像,出现交叉怎么办?

一、问题描述 用excel制作X-Y散点图,意外的出现了4个交叉点,而实际上的图表数据是没有交叉的。 二、模拟图表 模拟部分数据,并创建X-Y散点图,数据区域,X轴数据是依次增加的,因此散点图应该是没有交叉的。…

js好用的动态分页插件

js好用的动态分页插件是一款简单的分页样式插件,支持样式类型,当前页,每页显示数量,按钮数量,总条数,上一页文字,下一页文字,输入框跳转等功能。 js好用的动态分页插件

java基础:流程控制

一、用户交互Scanner (一)基础 1、概念:基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。java.util.Scanner 是 Java5的新特征,我们可以通过Scanne…

Java实现登录验证 -- JWT令牌实现

目录 1.实现登录验证的引出原因 2.JWT令牌2.1 使用JWT令牌时2.2 令牌的组成 3. JWT令牌(token)生成和校验3.1 引入JWT令牌的依赖3.2 使用Jar包中提供的API来实现JWT令牌的生成和校验3.3 使用JWT令牌验证登录3.4 令牌的优缺点 1.实现登录验证的引出 传统…

Spring 泛型依赖注入

Spring 泛型依赖注入,是利用泛型的优点对代码时行精简,将可重复使用的代码全部放到一个类之中,方便以后的维护和修改,同时在不增加代码的情况下增加代码的复用性。 示例代码: 创建实体类 Product package test.spri…

在电子表格中对多列数据去重

一、数据展示 二、代码 Sub 选中区域数据去重()Dim arr()Dim c, d, id Selection.Counti 0For Each c In SelectionIf c.Value <> "" ThenReDim Preserve arr(0 To i)arr(i) c.Valuei i 1End IfNextarr 一维去重(arr)i 0For Each c In Range("O2&…

当需要对多个表进行联合更新操作时,怎样确保数据的一致性?

文章目录 一、问题分析二、解决方案三、示例代码&#xff08;以 MySQL 为例&#xff09;四、加锁机制示例五、测试和验证六、总结 在数据库管理中&#xff0c;经常会遇到需要对多个表进行联合更新的情况。这种操作带来了一定的复杂性&#xff0c;因为要确保在整个更新过程中数据…

Charles拦截发送数据包-cnblog

Charles拦截发送数据包 打开允许断点 右键要打断点的数据包&#xff0c;打断点 重新发请求进入断点模式 修改完毕后发送

集成学习(三)GBDT 梯度提升树

前面学习了&#xff1a;集成学习&#xff08;二&#xff09;Boosting-CSDN博客 梯度提升树&#xff1a;GBDT-Gradient Boosting Decision Tree 一、介绍 作为当代众多经典算法的基础&#xff0c;GBDT的求解过程可谓十分精妙&#xff0c;它不仅开创性地舍弃了使用原始标签进行…

浪潮信息携手算力企业为华东产业集群布局提供高质量算力支撑

随着信息技术的飞速发展&#xff0c;算力已成为推动数字经济发展的核心力量。近日&#xff0c;浪潮信息与五家领先的算力运营公司在南京正式签署战略合作协议&#xff0c;共同加速华东地区智算基础设施布局&#xff0c;为区域经济发展注入新动力。 进击的算力 江苏持续加码智算…

论文回顾 | CVPR 2021 | How to Calibrate Your Event Camera | 基于图像重建的事件相机校准新方法

论文速览 | CVPR 2021 | How to Calibrate Your Event Camera | 基于图像重建的事件相机校准新方法 1 引言 在计算机视觉和机器人领域,相机校准一直是一个基础而又重要的问题。传统的相机校准方法主要依赖于从已知校准图案中提取角点,然后通过优化算法求解相机的内参和外参。这…

创新配置,秒级采集,火爆短视频评论抓取

快速采集评论数据的好处 快速采集评论数据是在当今数字信息时代的市场趋势分析和用户反馈分析中至关重要的环节。通过准确获取并分析大量用户评论&#xff0c;您将能够更好地了解消费者的需求、情感和偏好。集蜂云采集平台提供了一种简单配置的方法&#xff0c;使您能够快速采…

docker部署mycat,连接上面一篇的一主二从mysql

一、docker下载mycat镜像 查看安装结果 这个名称太长&#xff0c;在安装容器时不方便操作&#xff0c;设置标签为mycat docker tag longhronshens/mycat-docker mycat 二、安装容器 先安装一个&#xff0c;主要目的是获得配置文件 docker run -it -d --name mycat -p 8066:…

ubuntu设置开启自动挂载sftp

1. 前言 与其说 ubuntu 开启自动挂载 sftp, 更确切的说应该是 nautilus (ubuntu上默认的文件管理器) 开机自动挂载 sftp。 因为 这里即使选择永远记住&#xff0c;开机也不会自动挂载 sftp 2.设置方法 gnome-session-properties #开机只启动设置命令设置 gio mount sftp…

智慧文旅(景区)解决方案PPT(42页)

智慧文旅解决方案摘要 行业分析中国旅游业正经历消费大众化、需求品质化、发展全域化和产业现代化的发展趋势。《“十三五”旅游业发展规划》的发布&#xff0c;以及文化和旅游部的设立&#xff0c;标志着旅游业的信息化和智能化建设成为国家战略。2018年推出的旅游行业安全防范…

「技术分享」FDL对接金蝶云API取数

很多企业的ERP系统都在用金蝶云星空&#xff0c;金蝶云星空API是IT人员获取数据的重要来源&#xff0c; 常常用来生成定制化报表&#xff0c;进行数据分析&#xff0c;或是将金蝶云的数据与OA系统、BI工具集成。 通常情况下&#xff0c;IT人员需要使用Python、Java等语言编写脚…

从“钓”到“管”:EasyCVR一体化视频解决方案助力水域安全管理

一、背景 随着城市化进程的加快&#xff0c;越来越多的市民热衷于钓鱼活动。钓鱼活动在带来乐趣的同时&#xff0c;也伴随着一定的安全隐患。尤其是在一些危险水域&#xff0c;也经常出现垂钓者的身影&#xff0c;非法垂钓&#xff0c;这给城市管理带来了不小的阻力。传统的人…