实用指南:FreeRTOS 事件组详解

news/2025/9/28 21:13:43/文章来源:https://www.cnblogs.com/slgkaifa/p/19117618

实用指南:FreeRTOS 事件组详解

1. 事件组基本概念

1.1 与队列、信号量的区别

事件组与队列、信号量有两个主要区别:

唤醒机制不同:

  • 队列、信号量:事件发生时,只会唤醒一个任务

  • 事件组:事件发生时,会唤醒所有符合条件的任务,具有"广播"作用

事件处理方式不同:

  • 队列、信号量:消耗型资源(队列数据被读走就消失;信号量被获取后减少)

  • 事件组:被唤醒的任务可以选择是否清除事件

2. 事件组操作流程

2.1 基本使用流程

  1. 创建事件组

  2. 任务C、D等待事件

  3. 任务A、B产生事件

2.2 事件等待选项

  • 等待类型:可以等待某一位、某些位中的任意一个(或关系),或等待多位同时成立(与关系)

  • 清除选项:可选择在获取事件后清除或保留事件

3. 事件组API详解

3.1 创建事件组

动态创建:

c

EventGroupHandle_t xEventGroupCreate(void);
  • 内部自动分配事件组结构体内存

  • 返回句柄,非NULL表示成功

静态创建:

c

EventGroupHandle_t xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer);
  • 需要预先分配StaticEventGroup_t结构体

  • 避免动态内存分配,适合内存受限场景

3.2 删除事件组

c

void vEventGroupDelete(EventGroupHandle_t xEventGroup);
  • 删除动态创建的事件组,回收内存

  • 参数:要删除的事件组句柄

3.3 设置事件

在任务中设置:

c

EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet);
  • 设置事件组中的特定位

  • 可以同时设置多个位(如0x15表示设置bit4、bit2、bit0)

在ISR中设置:

c

BaseType_t xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,const EventBits_t uxBitsToSet,BaseType_t *pxHigherPriorityTaskWoken);
  • 通过向FreeRTOS后台任务发送队列数据来间接设置事件组

  • 避免在ISR中直接执行可能唤醒多个任务的操作

3.4 等待事件

c

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

参数详解:

参数说明
xEventGroup要等待的事件组句柄
uxBitsToWaitFor要等待的位(位掩码)
xWaitForAllBits测试方式:pdTRUE-所有位都为1(与关系),pdFALSE-任意位为1(或关系)
xClearOnExit退出时是否清除事件:pdTRUE-清除,pdFALSE-保留
xTicksToWait阻塞超时时间:0-立即返回,portMAX_DELAY-无限等待,具体tick数

返回值:

  • 事件发生时:返回"非阻塞条件成立"时的事件值

  • 超时退出:返回超时时刻的事件值

4. 事件等待示例分析

4.1 "与"关系等待(所有位必须为1)

c

// 示例1:等待bit0和bit2同时为1
EventBits_t uxBits = xEventGroupWaitBits(xEventGroup, 0x05,  // bit0和bit2pdTRUE, // 退出时清除pdTRUE, // 等待所有位portMAX_DELAY);// 事件组值变化过程:
// 初始值: 0100 (只有bit2为1) → 任务阻塞
// 设置bit0: 0101 → 满足条件,任务唤醒

4.2 "或"关系等待(任意位为1即可)

c

// 示例2:等待bit1或bit2任意一个为1
EventBits_t uxBits = xEventGroupWaitBits(xEventGroup,0x06,  // bit1和bit2pdTRUE, // 退出时清除pdFALSE, // 等待任意位100);   // 等待100个tick// 事件组值变化过程:
// 初始值: 0100 (bit2为1) → 立即满足条件,任务不阻塞

5. 实际代码示例

5.1 基本事件组使用

c

// 定义事件位
#define TASK_READY_BIT    (1 << 0)
#define DATA_READY_BIT    (1 << 1)
#define ERROR_BIT         (1 << 2)EventGroupHandle_t xEventGroup;// 任务A:设置事件
void vTaskA(void *pvParameters)
{while(1){// 执行某些操作...xEventGroupSetBits(xEventGroup, TASK_READY_BIT);vTaskDelay(pdMS_TO_TICKS(1000));}
}// 任务B:等待事件
void vTaskB(void *pvParameters)
{const EventBits_t xBitsToWaitFor = TASK_READY_BIT | DATA_READY_BIT;while(1){// 等待任意一个事件发生(或关系)EventBits_t xEvent = xEventGroupWaitBits(xEventGroup,           // 事件组句柄xBitsToWaitFor,        // 等待的位pdTRUE,                // 退出时清除事件pdFALSE,               // 或关系:任意位为1即可portMAX_DELAY);        // 无限等待if((xEvent & TASK_READY_BIT) != 0){// 处理TASK_READY事件}if((xEvent & DATA_READY_BIT) != 0){// 处理DATA_READY事件}}
}

5.2 复杂事件条件处理

c

// 等待多个条件同时满足(与关系)
void vComplexTask(void *pvParameters)
{// 等待系统就绪且数据有效const EventBits_t xAllRequiredBits = TASK_READY_BIT | DATA_READY_BIT;while(1){EventBits_t xEvent = xEventGroupWaitBits(xEventGroup,xAllRequiredBits,pdTRUE,        // 清除事件pdTRUE,        // 与关系:所有位必须为1pdMS_TO_TICKS(5000));  // 最多等待5秒if((xEvent & xAllRequiredBits) == xAllRequiredBits){// 所有条件满足,执行操作}else{// 超时,处理超时逻辑}}
}

6. 重要注意事项

6.1 原子操作优势

使用xClearOnExit参数为pdTRUE时,事件组的测试和清零在xEventGroupWaitBits()函数内部原子完成,避免了任务切换导致的事件状态不一致问题。

6.2 ISR中的特殊处理

在ISR中使用xEventGroupSetBitsFromISR()时需要注意:

  • 实际设置操作由后台任务执行,存在延迟

  • 可能唤醒多个任务,带来不确定性

  • 需要检查pxHigherPriorityTaskWoken参数,必要时进行任务切换

6.3 事件位管理

  • 合理规划事件位分配,避免冲突

  • 使用宏定义提高代码可读性

  • 注意事件位的清除时机,避免误清除

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

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

相关文章

大型网站开发方案网站设计面试问题

论文题目&#xff1a;Vision Transformers Need Registers 论文链接&#xff1a;https://arxiv.org/abs/2309.16588 视觉Transformer&#xff08;ViT&#xff09;目前已替代CNN成为研究者们首选的视觉表示backbone&#xff0c;尤其是一些基于监督学习或自监督学习预训练的ViT&a…

宁夏考试教育网站oa电子办公系统

根据上面一篇随笔所介绍的PC购买流程的项目&#xff0c;在项目中&#xff0c;需要有一个生成订单的功能&#xff0c;能够使得Admin很方便的在获得批准的申请中选取一些来生成订单&#xff0c;要求界面操作简单明了&#xff0c;大概的效果图如下&#xff1a; 点击checkbox&#…

[ABC425C] Rotate and Sum Query 题解

思路 对于操作二,多次求 $ \displaystyle \sum_{i=l}^r A_i $,不难想到前缀和。所以先记录 \(A\) 的前缀和。 对于操作一,我们不用按题意模拟,直接记录一共偏移了多少。以后出现操作二时直接根据偏移量输出偏移前 …

C语言网站开发pdf音乐网页设计材料加字加图片

本次由快手刘建刚老师分享&#xff0c;内容主要分为三部分。首先介绍流式计算的基本概念&#xff0c; 然后介绍 Flink 的关键技术&#xff0c;最后讲讲 Flink 在快手生产实践中的一些应用&#xff0c;包括实时指标计算和快速 failover。 一、流式计算的介绍 流式计算主要针对 u…

用名字做壁纸网站哪里有创建网站的

String 在编程中被广泛使用&#xff0c;所以掌握 String 和 int 的相互转换方法是极其重要的。 String转换为int String 字符串转整型 int 有以下两种方式&#xff1a; Integer.parseInt(str)Integer.valueOf(str).intValue()注意&#xff1a;Integer 是一个类&#xff0c;是…

制作高端网站公司排名网络营销推广seo

关于单引号和双引号 当输出的字符串内部没有单引号的时候&#xff0c;外面可以用单引号&#xff0c; 但是如果内部有了单引号&#xff0c;那么外部只能用双引号。 dict {Name: Zara, Age: 7, Class: First} print(dict) print (dict[Name]: , dict[Name]) print ("dic…

线程--基本使用、线程常用方法

2.2 继承Thread vs 实现 Runnable 的区别从java的设计来看,通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,从jdk帮助文档我们可以看到Thread类本身就实现了Runnable接口 实现Runnable接口方式更加适合…

酵母表面展示技术:从蛋白分析到多领域应用,解锁可持续发展的生物新工具

在细胞表面展示技术家族中,酵母表面展示(YSD)技术凭借 “功能集成度高、应用场景广” 的特性,成为生物技术领域的 “多面手”。它通过将目的蛋白精准锚定在酵母细胞表面,既赋予酵母宿主新的生物学功能,又能结合流…

9/28数学错题分析

数学错题分析 1.漏解。在做的时候知道还有别的解,但是想不出来怎么算了所以就有一个没算出来。 原因:思路不够开拓,没有用上所有的运算方法 2.不等式是否取等号检验的方式有问题,导致没有发现有问题的地方。 需要重…

linux查找指定字符串的三种方法 - 指南

linux查找指定字符串的三种方法 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

给你一个网站怎么做的西安网站设计建设公司 交通

引言 在开发我的笔记系统时&#xff0c;我遇到了一个问题。问题是&#xff0c;在api-gate服务中&#xff0c;我需要验证用户的access_code&#xff0c;但是access_code的生成逻辑是在auth2服务中实现的。这个问题从架构设计的层面上看&#xff0c;就是一个高耦合度问题。高耦合…

task

task1.c// 打印一个字符小人 #include <stdio.h> int main() {printf(" O \n");printf("<H>\n");printf("I I\n");return 0; }task1_1.c// 打印一个字符小人 #include <…

深入解析:自动驾驶中的传感器技术53——Radar(14)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

9/28

9/28今天学习了离散的自反,对称等性质。进一步了解了马克思主义的形成,当该说不说这个理论好难理解

实用指南:嵌入式面试高频(十二)!!!C++语言(嵌入式八股文,嵌入式面经)c++11新特性

实用指南:嵌入式面试高频(十二)!!!C++语言(嵌入式八股文,嵌入式面经)c++11新特性pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !importa…

2025 年陶瓷配件厂家 TOP 企业品牌推荐排行榜,电子,氧化铝,氧化锆,氮化铝,工业,精密,结构陶瓷配件,陶瓷柱塞配件,陶瓷刀片配件,陶瓷导轮配件公司推荐

在高端制造产业快速升级的当下,陶瓷配件凭借耐磨、耐高温、绝缘等优异特性,成为电子、航空航天、新能源等领域的核心组件。然而,市场上陶瓷配件品牌数量众多,产品质量参差不齐,材料性能差异显著,从普通氧化铝制品…

做视频网站 视频放在哪多地优化防控举措方便民众生活

团队管理规划有4个互相关联的要素&#xff1a; 职能目标团队路径在未来的3个月&#xff0c;6个月&#xff0c;1年&#xff0c;2年&#xff0c;3年&#xff0c;5年中&#xff0c;你希望带着你的团队抵达一个什么样的目的地&#xff0c;也就是团队的目标。 更加清楚目标意味着什么…

2025-2026-1 20231301 《信息安全设计》第三周学习总结

View Post2025-2026-1 20231301 《信息安全设计》第三周学习总结2025-2026-1 20231301 《信息安全设计》第三周学习总结 目录作业信息学习内容总结杂凑函数概述1. 基本概念2. 核心特性3. 安全要求杂凑函数分类1. 不带密…

SQL逐字稿

古法处理中...

2025攻丝机厂家 TOP 企业品牌推荐排行榜,全自动,半自动,转盘,伺服,平推,全自动钻孔,半自动钻孔攻丝机公司推荐

引言在工业自动化加速渗透的当下,攻丝机作为机械加工领域的关键设备,其性能与稳定性直接影响企业生产效率与产品精度。然而当前市场中,攻丝机产品质量参差不齐,部分设备存在故障率高、精度不足、适配性差等问题,不…