[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 );}}

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

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

相关文章

适用于Mac和Windows的最佳iPhone恢复软件

本文将指导您选择一款出色的iPhone数据恢复软件来检索您的宝贵数据。 市场上有许多所谓的iPhone恢复程序。各种程序很难选择并选择其中之一。一旦您做出了错误的选择,您的数据就会有风险。 最好的iPhone数据恢复软件应包含以下功能。 1.安全可靠。 2.恢复成功率高…

Windows下Visual Studio 中配置第一个CUDA工程

今天整NVIDIA 的CUDA 安装和第一个CUDA 代码,顺便添加一个有CUDA工程的空框架。 (1)首先确认自己的CUDA 已经安装成功 >>cmd 进入命令窗,在窗口输入查看cuda 是否安装成功,能查到CUDA的版本号,表示安…

基于python的数据分解-趋势-季节性-波动变化

系列文章目录 前言 时间序列数据的分解,一般分为趋势项,季节变化项和随机波动项。可以基于加法或者乘法模型。季节变化呈现出周期变化,因此也叫季节效应(周期)。 一、数据分解步骤 (1)估计时间序列的长期…

仪器校准后出了校准证书后,是不是就代表仪器合格了?

仪器校准是一门技术活,对于从事生产制造的企业而言,是不可或缺的一环,因为这与产品质量密切相关。所以,了解仪器校准的相关知识也变得尤为重要。 在拿到校准证书后,是不是说明仪器合格了?相信不少企业品管人…

指针回顾.

指针的主要作用:提供一种间接访问数据的方法 1.地址:区分不同内存空间的编号 2.指针:指针就是地址,地址就是指针 3.指针变量:存放指针的变量称为指针变量,简称为指针 1.指针的定义 int *p NULL; int *q NULL; char *p NULL; double *p NUL…

PCDN技术如何提高内容分发效率?(贰)

PCDN技术通过以下方式提高内容分发效率: 1.利用用户设备作为分发节点:与传统的 CDN技术主要依赖中心化服务器不同, PCDN技术利用用户的设备作为内容分发的节点。当用户下载内容时,他们的设备也会成为内容分发的一部分,将已下载的内容传递给其…

STL--求交集,并集,差集(set_intersection,set_union,set_difference)

set_intersection(重要) 求两个有序的序列的交集. 函数声明如下: template<class InputIterator1, class InputIterator2, class OutputIterator>OutputIterator set_intersection(InputIterator1 _First1, //容器1开头InputIterator1 _Last1, //容器2结尾(不包含)Inp…

jenkins配置gitee源码地址连接不上

报错信息如下&#xff1a; 网上找了好多都没说具体原因&#xff0c;最后还是看jenkins控制台输出日志发现&#xff1a; ssh命令执行失败&#xff08;git环境有问题&#xff0c;可能插件没安装成功等其他问题&#xff09; 后面发现是jenkins配置git的地方git安装路径错了。新手…

加入新数据预测,基于黏菌优化算法SMA优化SVM支持向量机回归预测(多输入单输出)

加入新数据预测&#xff0c;基于黏菌优化算法SMA优化SVM支持向量机回归预测&#xff08;多输入单输出&#xff09; 1.数据均为Excel数据&#xff0c;直接替换数据就可以运行程序。 2.所有程序都经过验证&#xff0c;保证程序可以运行。 3.具有良好的编程习惯&#xff0c;程序…

cmake find_package 使用笔记

目录 1 find_package2 config mode2.1 搜索的文件名2.2 搜索路径 3 module mode3.1 搜索的文件名3.2 搜索路径 参考 1 find_package 这是官方文档 下面是学习总结&#xff1a; 首先是find_package的作用是什么&#xff1f;引入预编译的库。 find_package有两种模式&#xff1a…

【LInux】从动态库的加载深入理解页表机制

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

【MindSpore学习打卡】应用实践-自然语言处理-基于RNN的情感分类:使用MindSpore实现IMDB影评分类

情感分类是自然语言处理&#xff08;NLP&#xff09;中的一个经典任务&#xff0c;广泛应用于社交媒体分析、市场调研和客户反馈等领域。本篇博客将带领大家使用MindSpore框架&#xff0c;基于RNN&#xff08;循环神经网络&#xff09;实现一个情感分类模型。我们将详细介绍数据…

Nettyの参数优化简单RPC框架实现

本篇介绍Netty调优&#xff0c;在上篇聊天室的案例中进行改造&#xff0c;手写一个简单的RPC实现。 1、超时时间参数 CONNECT_TIMEOUT_MILLIS 是Netty的超时时间参数&#xff0c;属于客户端SocketChannel的参数&#xff0c;客户端连接时如果一定时间没有连接上&#xff0c;就会…

Spring Cloud 是什么?(Spring Cloud 组件介绍)

什么是 Spring Cloud&#xff1f; Spring Cloud 是微服务系统架构的一站式解决方案&#xff0c;是各个微服务架构落地技术的集合体&#xff0c;让架构师、 开发者在使用微服务理念构建应用系统的时候&#xff0c; 面对各个环节的问题都可以找到相应的组件来处理&#xff0c;比…

React 19 竞态问题解决

竞态问题/竞态条件 指的是&#xff0c;当我们在交互过程中&#xff0c;由于各种原因导致同一个接口短时间之内连续发送请求&#xff0c;后发送的请求有可能先得到请求结果&#xff0c;从而导致数据渲染出现预期之外的错误。 因为防止重复执行可以有效的解决竞态问题&#xff0…

聊天广场(Vue+WebSocket+SpringBoot)

由于心血来潮想要做个聊天室项目 &#xff0c;但是仔细找了一下相关教程&#xff0c;却发现这么多的WebSocket教程里面&#xff0c;很多都没有介绍详细&#xff0c;代码都有所残缺&#xff0c;所以这次带来一个比较完整得使用WebSocket的项目。 目录 一、效果展示 二、准备工…

html+css+js图片手动轮播

源代码在界面图片后面 轮播演示用的几张图片是Bing上的&#xff0c;直接用的几张图片的URL&#xff0c;谁加载可能需要等一下&#xff0c;现实中替换成自己的图片即可 关注一下点个赞吧&#x1f604; 谢谢大佬 界面图片 源代码 <!DOCTYPE html> <html lang&quo…

安全测试之使用Docker搭建SQL注入安全测试平台sqli-labs

1 搜索镜像 docker search sqli-labs 2 拉取镜像 docker pull acgpiano/sqli-labs 3 创建docker容器 docker run -d --name sqli-labs -p 10012:80 acgpiano/sqli-labs 4 访问测试平台网站 若直接使用虚拟机&#xff0c;则直接通过ip端口号访问若通过配置域名&#xff0…

第十五章 Nest Pipe(内置及自定义)

NestJS的Pipe是一个用于数据转换和验证的特殊装饰器。Pipe可以应用于控制器&#xff08;Controller&#xff09;的处理方法&#xff08;Handler&#xff09;和中间件&#xff08;Middleware&#xff09;&#xff0c;用于处理传入的数据。它可以用来转换和验证数据&#xff0c;确…

【Linux进阶】文件系统5——ext2文件系统(inode)

1.再谈inode (1) 理解inode&#xff0c;要从文件储存说起。 文件储存在硬盘上&#xff0c;硬盘的最小存储单位叫做"扇区"&#xff08;Sector&#xff09;。每个扇区储存512字节&#xff08;相当于0.5KB&#xff09;。操作系统读取硬盘的时候&#xff0c;不会一个个…