【FreeRTOS基础入门】事件组与同步点

news2024/11/25 21:23:59

文章目录

  • 前言
  • 一、事件组是什么
    • 案例
    • 1.1 事件组的概念
  • 二、事件组的操作
    • 2.1 事件组与其他实现同步与互斥方法的区别
    • 2.2 创建事件组
    • 2.3 删除事件组
    • 2.4 设置事件
    • 2.5 等待事件
    • 2.6 示例代码
  • 三、同步点
    • 3.1 同步点是什么
    • 3.2 设置同步点
  • 总结


前言

FreeRTOS是一个广泛应用于嵌入式系统的实时操作系统内核,提供了丰富的功能和组件,以帮助开发者构建可靠的嵌入式应用程序。其中,事件组(Event Groups)是一种重要的机制,用于任务之间的事件通知和同步。本文将重点介绍FreeRTOS中事件组的基础知识,以帮助初学者更好地理解和应用这一功能。

在嵌入式系统中,多个任务可能需要协同工作,彼此之间需要进行事件通知和同步。事件组提供了一种有效的方式来管理和触发事件,从而实现任务之间的同步与通信。通过学习事件组的概念、使用方法以及实际应用场景,开发者可以更好地设计和实现复杂的嵌入式系统。


一、事件组是什么

案例

学校组织秋游,组长在等待:

  • 张三:我到了
  • 李四:我到了
  • 王五:我到了
    组长说:好,大家都到齐了,出发!
    秋游回来第二天就要提交一篇心得报告,组长在焦急等待:张三、李四、王五谁先写好就交谁的。
    在这个日常生活场景中:
  • 出发:要等待这 3 个人都到齐,他们是"与"的关系
  • 交报告:只需等待这 3 人中的任何一个,他们是"或"的关系
    在 FreeRTOS 中,可以使用事件组(event group)来解决这些问题。

1.1 事件组的概念

在这里插入图片描述

事件组可以简单的认为就是一个整数,你可以去设置整数的某一位为1代表有事件,设置0为无事件。
你可以去等待一个位或者多个位
下面的为事件组结构体:

typedef struct xEventGroupDefinition
{
	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

	#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成员为事件组,xTasksWaitingForBits用来存储等待事件的任务

事件组用一个整数来表示,其中的高 8 位留给内核使用,只能用其他的位来表示事件。
那么这个整数是多少位的?
 如果 configUSE_16_BIT_TICKS 是 1,那么这个整数就是 16 位的,低 8 位
用来表示事件
 如果 configUSE_16_BIT_TICKS 是 0,那么这个整数就是 32 位的,低 24 位
用来表示事件
 configUSE_16_BIT_TICKS 是用来表示 Tick Count 的,怎么会影响事件组?
这只是基于效率来考虑
 如果 configUSE_16_BIT_TICKS 是 1,就表示该处理器使用 16 位更高效,所
以事件组也使用 16 位
 如果 configUSE_16_BIT_TICKS 是 0,就表示该处理器使用 32 位更高效,所
以事件组也使用 32 位

二、事件组的操作

2.1 事件组与其他实现同步与互斥方法的区别

事件组和队列、信号量等不太一样,主要集中在 2 个地方:
 唤醒谁?
 队列、信号量:事件发生时,只会唤醒一个任务
 事件组:事件发生时,会唤醒所有符号条件的任务,简单地说它有"广播"的
作用
 是否清除事件?
 队列、信号量:是消耗型的资源,队列的数据被读走就没了;信号量被获取后就减少了
在这里插入图片描述

 事件组:被唤醒的任务有两个选择,可以让事件保留不动,也可以清除事件以上图为列,事件组的常规操作如下:
 先创建事件组
 任务 C、D 等待事件:
 等待什么事件?可以等待某一位、某些位中的任意一个,也可以等待多位。
简单地说就是"或"、"与"的关系。
 得到事件时,要不要清除?可选择清除、不清除。
 任务 A、B 产生事件:设置事件组里的某一位、某些位

2.2 创建事件组

我们可以使用下面这个函数进行动态的创建事件组

EventGroupHandle_t xEventGroupCreate( void );

他返回的是一个事件组的handle

我们也可以加个static表示要创建静态的事件组

EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer );

你只需要提供事件组的Buffer即可。

2.3 删除事件组

我们可以使用下面这个函数删除一个事件组:

void vEventGroupDelete( EventGroupHandle_t xEventGroup );

参数为要删除事件组的handle

2.4 设置事件

在任务中,你可以使用下面这个函数进行设置某一位:

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToSet );

参数二怎么填写?
他的定义是这样的:typedef TickType_t EventBits_t;类型就是uint32_t,如果你设置的是32位的话
我们可以来让他的某一个位为1,代表这个位有事件了
比如我们想让第5位就这样:1<<5,如果想要两个就使用1 << 5 | 1 << 4,使用或运算符

如果你需要在中断中使用,函数名称只需要加个ISR

BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, 
const EventBits_t uxBitsToSet, 
BaseType_t *pxHigherPriorityTaskWoken );

他的参数3用来告诉调用者,在设置事件组位的过程中是否有更高优先级的任务被唤醒了。
因此,当你调用 xEventGroupSetBitsFromISR 函数时,如果有更高优先级的任务被唤醒了,那么 pxHigherPriorityTaskWoken 参数会被设置为非零值;如果没有更高优先级的任务被唤醒,那么 pxHigherPriorityTaskWoken 参数会被设置为零。这样,在 ISR 结束后,FreeRTOS 就知道是否需要进行任务切换。

2.5 等待事件

我们可以使用下面这个函数来等待某个事件:

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

参数2意义为等待哪些位。参数3为是否在这个函数结束时清楚等待位。参数4为,如果你的参数2等待了多个位,比如0和5,是否要等待这两个位全部有了事件在唤醒任务,还是任意一个都行,他们可以填pdTRUE或者pdFLASE

2.6 示例代码

#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"

// 定义事件组句柄
EventGroupHandle_t xEventGroup;

// 定义事件组位
#define BIT_0 (1 << 0)
#define BIT_1 (1 << 1)

// 任务1,等待事件组位 BIT_0
void vTask1(void *pvParameters) {
    while (1) {
        // 等待事件组位 BIT_0,设置 clear_on_exit 标志位,表示等待后清除
        EventBits_t uxBits = xEventGroupWaitBits(xEventGroup, BIT_0, pdTRUE, pdFALSE, portMAX_DELAY);
        if (uxBits & BIT_0) {
            // 收到 BIT_0 位的信号
            // 执行相应操作...
        }
    }
}

// 任务2,等待事件组位 BIT_1
void vTask2(void *pvParameters) {
    while (1) {
        // 等待事件组位 BIT_1,设置 clear_on_exit 标志位,表示等待后清除
        EventBits_t uxBits = xEventGroupWaitBits(xEventGroup, BIT_1, pdTRUE, pdFALSE, portMAX_DELAY);
        if (uxBits & BIT_1) {
            // 收到 BIT_1 位的信号
            // 执行相应操作...
        }
    }
}

// 主函数
int main(void) {
    // 创建事件组
    xEventGroup = xEventGroupCreate();

    // 创建任务1,优先级较高
    xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, NULL, 2, NULL);

    // 创建任务2,优先级较低
    xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

    // 启动调度器
    vTaskStartScheduler();

    // 如果调度器启动失败,进行错误处理
    for (;;);

    return 0;
}

三、同步点

3.1 同步点是什么

有一个事情需要多个任务协同,比如:
 任务 A:炒菜
 任务 B:买酒
 任务 C:摆台
 A、B、C 做好自己的事后,还要等别人做完;大家一起做完,才可开饭
同步点就是如果你做好了,你需要等待其他和你一起干这个事情的任务,如果没有做完就接着做,直到做完,当需要同步的任务都ok了,就进行下一步的执行,少一个没做完都不行

3.2 设置同步点

我们可以使用下面这个函数设置一个同步点:

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

参数2为你要设置哪些事件,表示你完成了这个事件
参数3表示你要等待哪些事件完成。
当你设置的参数3事件都ok之后,他就会往下走


总结

事件组作为FreeRTOS的一个重要特性,为嵌入式系统的开发提供了强大的事件管理机制。通过使用事件组,开发者可以轻松地实现任务之间的事件通知和同步,提高系统的灵活性和效率。在实际应用中,合理利用事件组可以简化任务之间的协作逻辑,使系统更加可靠和稳定。希望本文能够为初学者提供一个清晰的入门指南,让大家更好地利用FreeRTOS的事件组功能进行嵌入式开发。

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

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

相关文章

vue3中使用 tui-image-editor进行图片处理,并上传

效果图 下载包 pnpm i tui-image-editor pnpm i tui-color-picker调用组件 //html部分 <el-dialog v-model"imgshow" destroy-on-close width"40%" draggable align-center :show-close"true":close-on-click-modal"false">&l…

windows极限摸鱼软件(仅6678kb)

时间过得真快啊&#xff0c;不知不觉春节假期就过完了。你已经开始工作了吗&#xff1f;反正我是一直没闲着。 歇的时间久了&#xff0c;一上班这节奏很难一下子转换过来。也可能刚上班&#xff0c;没什么事情做&#xff0c;有点无聊。 &#xff08;好吧&#xff0c;我承认了…

Java 面向对象进阶 11 多态的优势和弊端(黑马)

优势&#xff1a; 代码&#xff1a; public class test {public static void main(String[] args) {Animal a new Dog();a.eat(); } } class Animal{public void eat(){System.out.println("动物再吃东西");} } class Dog extends Animal{Overridepublic void eat(…

如何修改unity的背景颜色

要在Unity中将背景颜色设为黑色&#xff0c;可以按照以下步骤进行&#xff1a; 1、在Unity编辑器中&#xff0c;选择你想要修改背景颜色的摄像机对象&#xff08;一般是Main Camera&#xff09;。 2、在Inspector面板中&#xff0c;找到"Clear Flags"&#xff08;清…

Leetcode155(设计最小栈)

例题&#xff1a; 分析&#xff1a; 题目要求我们必须在常数时间内检索到最小元素。 我们可以使用两个栈&#xff08;A、B&#xff09;来实现&#xff0c;A栈用来正常存储数据、弹出数据&#xff0c; B栈用于存储A栈中的最小元素&#xff0c;如下图&#xff1a; 刚开始&#…

三十年一个大轮回!日股突破“泡沫时期”历史高点

2月22日周四&#xff0c;英伟达四季报业绩超预期&#xff0c;而且本季度业绩指引非常乐观&#xff0c;提振美股股指期货并成为芯片股和AI概念股情绪的重要催化剂。今日亚洲芯片股和AI股起飞&#xff0c;日本在芯片股的带动下突破1989年泡沫时期以来的历史最高收盘价。 美股方面…

SqlServer2016离线安装--Microsoft R Open 和 Microsoft R Server安装文件位置

问题 SQL SERVE 2016离线安装&#xff0c;会出现“Microsoft R Open 和 Microsoft R Server 脱机安装”的界面&#xff0c; 无法点击下一步的情况&#xff0c;如下图&#xff1a; 原因 离线安装时需要下载两个文件 解决方案 1、访问路径下载文件 https://go.microsoft.c…

MATLAB 导出可编辑的eps格式图像

任务描述&#xff1a;部分期刊要求提交可编辑的eps格式图像&#xff0c;方便美工编辑对图像进行美化 我试了直接print或者在figure窗口导出&#xff0c;发现导出的文件放到Adobe AI中并不能编辑&#xff0c;经Google找到解决办法&#xff1a; %EPS exportgraphics(gcf,myVect…

Nginx基础入门

一、Nginx的优势 nginx是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个SMTP&#xff08;邮局&#xff09;服务器。 Nginx的web优势&#xff1a;IO多路复用&#xff0c;时分多路复用&#xff0c;频分多路复用 高并发&#xff0c;IO多路复用&#xff0c;epoll&#xf…

2024年1月手机市场行业分析:苹果手机份额骤降,国产高端手机成功逆袭!

小米Ultra发布。 一方面&#xff0c;我们有望看到国产手机再一次超越自己的决心&#xff0c;继续创新追逐高端&#xff1b;另一方面&#xff0c;我们也不得不正视目前手机市场所面临的危机状态。 2024年1月的线上手机市场远不如去年。根据鲸参谋数据显示&#xff0c;今年1月京…

linux系统内核升级

1.查看旧版本内核 2.导入密钥 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 3.安装yum源 rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm4.启用elrepo-kernel仓库并安装最新内核版本 yum --enablerepoelrepo-kernel install …

【AIGC】开源音频工具AudioCraft

AudioCraft是一个开源框架&#xff0c;旨在生成高质量的音频&#xff0c;适用于音乐、声音生成和压缩等多种应用。 先听效果&#xff1a; aimusic 它由三个模型组成&#xff1a;MusicGen、AudioGen和EnCodec。 *MusicGen&#xff1a;*这个模型使用了Meta拥有和特别许可的音乐进…

WP----Look 我看的见你,你却看不见我 tips:sql injection tips2: mysql 字符集

0x00 题目连接打开后&#xff0c;是空白的&#xff0c;源代码也是空白的 这种情况就抓包&#xff0c;看请求包和相应包里面是否有提示 相应包中存在很特别的响应头X-HT: verify 可能是参数&#xff0c;传递任意参数过去 0x01 传递5个长度的参数时&#xff0c;返回 说明参数的…

相机图像质量研究(35)常见问题总结:图像处理对成像的影响--运动噪声

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

使用 C++23 协程实现第一个 co_await 同步风格调用接口--Qt计算文件哈希值

C加入了协程 coroutine的特性&#xff0c;一直没有动手实现过。看了网上很多文章&#xff0c;已经了解了协程作为“可被中断和恢复的函数”的一系列特点。在学习过程中&#xff0c;我发现大多数网上的例子&#xff0c;要不就是在main()函数的控制台程序里演示yeild,await, resu…

命令执行 [WUSTCTF2020]朴实无华1

做题&#xff1a; 打开题目 我们用dirsearch扫描一下看看 扫描到有robots.txt&#xff0c;访问一下看看 提示我们 /fAke_f1agggg.php 那就访问一下&#xff0c;不是真的flag bp抓包一下 得到提示&#xff0c; /fl4g.php&#xff0c;访问一下看看 按alt&#xff0c;点击修复文…

IP地理位置查询定位:技术原理与实际应用

在互联网时代&#xff0c;IP地址是连接世界的桥梁&#xff0c;而了解IP地址的地理位置对于网络管理、个性化服务以及安全监控都至关重要。IP数据云将深入探讨IP地理位置查询定位的技术原理、实际应用场景以及相关的隐私保护问题&#xff0c;旨在为读者提供全面了解和应用该技术…

Shopee平台选品原则指南:如何科学有效地进行产品选品

在当今激烈竞争的电商市场中&#xff0c;如何在Shopee平台上选择适合的产品进行销售&#xff0c;是每位卖家都要面对的重要问题。针对这一挑战&#xff0c;我们整理了一些关键原则&#xff0c;帮助卖家们在选品过程中更加科学和有效地进行决策。 先给大家推荐一款shopee知虾数…

一文弄明白KeyedProcessFunction函数

引言 KeyedProcessFunction是Flink用于处理KeyedStream的数据集合&#xff0c;它比ProcessFunction拥有更多特性&#xff0c;例如状态处理和定时器功能等。接下来就一起来了解下这个函数吧 正文 了解一个函数怎么用最权威的地方就是 官方文档 以及注解&#xff0c;KeyedProc…

stm32和嵌入式linux可以同步学习吗?

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「stm3的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;如果需要使用STM32&#xff0c;建…