个人笔记--FreeRTOS事件标志组

2023-11-07

FreeRTOS事件标志组

简介
事件的基本概念

事件是一种实现任务间通信的机制,主要用于实现任务间的同步,与信号量不同的是:事件通信只能传输事件是否发生,不能传递数据。而且事件可以实现一对多,多对多的同步。
一个任务可以等待多个事件的发送:可以是一个事件发生时唤醒任务进行事件处理;也可以是几个事件都发生后才唤醒任务进行事件处理,同样可以是多个任务同步多个事件

事件组的优点:多个事件的集合叫做事件组

通常编程时如果要定义一个标志位,最长用的类型是char类型,在STM32中,char类型要占用8位bit,可能我们用标志位只是用来1表示事件发生,0表示事件没有发生。使用8位比较浪费RAM空间,事件组可以很好的节省RAM空间。在FreeRTOS中事件组存储在一个EventBits_tl类型的变量中,这个变量还有一个宏来控制。

configUSE_16_BIT_TICKS 定义为 1 时变量uxEventBits为16位的,但是只能存储8个位来存储事件。

configUSE_16_BIT_TICKS 定义为 0 时变量uxEventBits为32位的,但是只能存储24个位来存储事件。

每一位代表一个事件,任务通过逻辑与或者逻辑或与一个或多个事件建立关联。

事件组特点
  • 事件只与任务相关联,事件之间相互独立。
  • 事件仅用于同步,不提供数据传输功能。
  • 事件无排队性,多次设置一个事件(任务还没有读取走),等效于只设置一次
  • 允许多个任务对同一事件进行读写操作
  • 支持等待超时
事件应用场景
  1. 做标志位

    用事件做标志位,用来标志某些情况是否发生。多个事件标志位可以组成事件组统一管理。

    比如设备启动,有些需要进行一些列自检,当全部自检成功,设备才能启动正常,这时可以用事件作为自检成功或失败的标志位

事件运作机制
  1. 接收事件时,可以根据需要关注单个或多个事件类型,事件接收成功后可以选择是否清空事件标志位。

  2. 设置事件时,通过移位操作,对事件集合的对应事件位置1,可以同时写多个事件类型,设置事件成功后可能会出发任务调度。

  3. 清除事件时,根据传入参数事件句柄和待清除的事件类型,对事件对应为进行清0操作。

  4. 事件唤醒机制,当任务等待某个或者多个事件发生而进入阻塞态,当事件发生后任务进入就绪态,用户可以指定阻塞时间。
    在这里插入图片描述

事件不与任务关联,事件之间相互独立,每一位表示一种事件类型,只有0或1两种情况。

事件函数接口讲解

事件控制块

/*------------------------------------------------------------------------------
	如果宏 configUSE_16_BIT_TICKS 定义为 1,那么变量uxEventBits 就 是 16 位 的 , 
	其 中 有 8 个 位 用来存储 事 件 组 , 如 果 宏configUSE_16_BIT_TICKS 定义为 0,
	那么变量 uxEventBits 就是 32 位的,其中有 24 个位用来存储事件组
----------------------------------------------------------------------------------*/
EventGroupHandle_t Event_Handle =NULL;//定义事件组控制句柄

事件创建函数 xEventGroupCreate( )

/*-------------------------------------------------------------------------------
	事件创建函数(动态),函数参数为空,返回值是一个EventGroupHandle_t类型的句柄
-----------------------------------------------------------------------------------*/
 EventGroupHandle_t xEventGroupCreate( void );

//使用实例
static EventGroupHandle_t Event_Handle =NULL;//定义事件组句柄
Event_Handle = xEventGroupCreate(); 
if (NULL != Event_Handle)
	printf("Event_Handle 事件创建成功!\r\n");
else
	/* 创建失败,应为内存空间不足 */

事件删除函数 vEventGroupDelete( )

/*---------------------------------------------------------------------------------
	事件删除函数,只有被创建成功的事件才能被删除,该函数不能用在中断里,当事件被删除后阻塞
	在事件组上的任务或被解锁。
------------------------------------------------------------------------------------*/
使用实例:
static EventGroupHandle_t Event_Handle = NULL;
Event_Handle = xEventGroupCreate();
if(NULL!=Event_Handle)
{
    printf("Event_Handle事件创建成功\r\n");
    xEventGroupCreate(Event_Handle);//删除事件组
}
else
{
    printf("Event_Handle事件创建失败\r\n");//空间不足,创建失败
}

事件组置位函数 xEventGroupSetBits()(任务)

/*---------------------------------------------------------------------------------
	事件组置位函数,用于置位事件组中指定的位,当位被置为后,阻塞在该位上的任务将会被解锁。
	该函数不能在中断中使用。
	xEventGroup---事件句柄
	xBitsToSet----指定事件中的事件标志位(设置为0X08只置位位3,设置为0X09则置位位3和位0)
	返回值是事件组中的值
------------------------------------------------------------------------------------*/
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,const EventBits_t xBitsToSet );

#define KEY1_EVENT (0x01 << 0)//设置事件掩码的位 0 
#define KEY2_EVENT (0x01 << 1)//设置事件掩码的位 1

if(key==1)//如果按键1按下
    xEventGroupSetBits(Event_Handle,KEY1_EVENT);
if(key==2)//如果按键1按下
    xEventGroupSetBits(Event_Handle,KEY2_EVENT);

事件组置位函数 xEventGroupSetBitsFromISR()(中断)

xEventGroupSetBitsFromISR()xEventGroupSetBits()的中断版本,用于置位事件组中
指定的位。置位事件组中的标志位是一个不确定的操作,因为阻塞在事件组的标志位上的
任务的个数是不确定的。FreeRTOS 是不允许不确定的操作在中断和临界段中发生的,所以
xEventGroupSetBitsFromISR()给 FreeRTOS 的守护任务发送一个消息,让置位事件组的操作
在守护任务里面完成,守护任务是基于调度锁而非临界段的机制来实现的。

等待事件函数 xEventGroupWaitBits( )

/*----------------------------------------------------------------------------------
	等待事件函数
	xEventGroup:事件句柄
	uxBitsToWaitFor:一个按位或的值,指定需要等待事件组中的那些位置1
	xClearOnExit:传入pdTURE时唤醒任务后,清除事件标志位;传入pdFALSE时,不清除事件标志位
	xWaitForAllBits:传入pdTURE时-当指定位都置位后,才满足唤醒任务的条件。(逻辑与等待事件)
	传入pdFALSE时-当指定位有一个置位后,即可满足唤醒任务的条件。(逻辑或等待事件)
	xTicksToWait:超时等待时间。
	返回值:返回事件中的哪些事件标志位被置位,返回值很可能并不是用户指定的事件位,需要对返回
	值进行判断再处理。
-----------------------------------------------------------------------------------*/
EventBits_t xEventGroupWaitBits(const EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToWaitFor,
 const BaseType_t xClearOnExit,
 const BaseType_t xWaitForAllBits,
 TickType_t xTicksToWait );

清除事件组指定位函数 xEventGroupClearBits( )与 xEventGroupClearBitsFromISR( )

/*--------------------------------------------------------------------------------------
	如果在获取事件的时候没有将对应的标志位清除,那么就需要用这个函数来进行显式清除,
	EventGroupClearBits()函数不能在中断中使用,而是由具有中断保护功能的xEventGroupClearBitsFromISR() 
	来代替
	xEventGroup:事件句柄
	uxBitsToClear:指定事件组中的哪个位需要清除,如设置 uxBitsToSet 为0x08 则只清除位 3,如果设置
	uxBitsToSet 为 0x09 则位 3 和位 0 都需要被清除。
	返回值:事件在还没有清除指定位之前的值。
----------------------------------------------------------------------------------------*/
EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
BaseType_t xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );

事件标志组学习总结完毕,后续有新的笔记会重复更新。–add-by-wrs
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

个人笔记--FreeRTOS事件标志组 的相关文章

  • 如何使用 SOCKS 隧道在没有 VPN 的情况下安全地路由 Web 流量

    作者选择了COVID 19 救济基金接受捐赠作为为捐款而写程序 介绍 在某些时候 您可能会发现自己所在的网络不安全或防火墙限制过于严格 并且您需要确保没有人在监视您的流量 一种解决方案是使用 VPN 但许多 VPN 需要在您的计算机上安装特
  • Java 集合 sort()

    今天我们将研究Java集合的排序方法 在与java中的集合 我们经常需要对数据进行排序 Java 集合 sort Java Collections类为我们提供了非常方便的方法Collections sort 对所有进行排序List实施例如链
  • 提高 React 应用程序性能的 5 个技巧

    您的 React 应用程序是否感觉有点迟缓 您是否因为可能看到的内容而害怕打开 Chrome DevTools 中的 paint flash 试试这 5 个性能技巧 本文包含 React 开发的 5 个性能技巧 您可以使用此目录快速浏览本文
  • 如何在 Linux 上读取和设置环境变量和 Shell 变量

    介绍 当通过 shell 会话与服务器交互时 shell 会编译许多信息来确定其行为和对资源的访问 其中一些设置包含在配置设置中 而其他设置则由用户输入确定 shell 跟踪所有这些设置和详细信息的一种方法是通过它维护的一个称为环境 环境是
  • Python 当前日期时间

    我们可以使用Python datetime模块来获取本地系统的当前日期和时间 from datetime import datetime Current date time in local system print datetime no
  • 如何在 CentOS 7 上安装和使用 Docker

    介绍 Docker 是一个应用程序 可以让在容器中运行应用程序进程变得简单 容易 就像虚拟机一样 只是更便携 更资源友好 更依赖于主机操作系统 有关 Docker 容器的不同组件的详细介绍 请查看Docker 生态系统 常用组件简介 在 C
  • 如何在 Ubuntu 18.04 上安装/卸载 NodeJS

    NodeJS 是一个 JavaScript 框架 可让您轻松构建快速的网络应用程序 在本指南中 我们将深入研究如何在 Ubuntu 18 04 上安装 NodeJS 步骤 1 将 NodeJS PPA 添加到 Ubuntu 18 04 首先
  • 在 C/C++ 中使用 getch() 函数

    在本文中 我们将了解在 C C 中使用 getch 函数 如果您想读取从键盘输入的字符 getch 函数非常有用 虽然这不是 C 标准的一部分 但这仍然是 POSIX C 函数 因此 我们仍然可以在 Windows Linux Mac 上使
  • 如何保护 Ubuntu 14.04 上的 Redis 安装

    介绍 Redis 是一种内存中 NoSQL 键值缓存和存储 也可以持久保存到磁盘上 本教程展示如何实现 Redis 服务器的基本安全性 但是 请记住 Redis 是为以下用户而设计的 值得信赖的客户 in a 可信环境 本身没有强大的安全功
  • Python 漂亮打印 JSON

    我们可以使用Python json 模块漂亮地打印 JSON 数据 建议使用 json 模块来处理 JSON 文件 我们可以使用dumps 方法来获取格式漂亮的 JSON 字符串 1 Python漂亮打印JSON字符串 import jso
  • 如何在 JavaScript 中使用运算符进行数学运算

    介绍 数学运算是任何编程语言最基本和通用的功能之一 在 JavaScript 中 数字经常用于常见任务 例如查找浏览器窗口大小 获取货币交易的最终价格以及计算网站文档中元素之间的距离 尽管对数学的高度理解并不是成为一名有能力的开发人员的先决
  • 如何实现SQL INSTR()函数?

    嘿伙计 在这篇文章中 我们将了解SQL INSTR 函数详细 SQL INSTR 的工作原理 SQL 作为一种查询语言 包含各种内置函数来处理数据库的字符串数据值 SQL INSTR 函数就是这样一个有趣的函数 SQL INSTR func
  • Java 从 URL 下载文件

    今天我们将学习如何用java从URL下载文件 我们可以用java net URL openStream java程序中从URL下载文件的方法 我们可以使用Java NIO Channels或Java IO InputStream从URL打开

随机推荐

  • 如何在Java中合并两个列表?

    在 Java 中合并两个列表通常是一个有用的操作 这些列表可以是 ArrayList 或 LinkedList 如何在 Java 中合并两个列表 在 Java 中 我们可以通过多种方式合并两个列表 让我们探索一些简单的方法来完成您的工作 1
  • 如何在 Ubuntu 18.04 上使用 Let's Encrypt 保护 Apache

    介绍 Let s Encrypt 是一个证书颁发机构 CA 提供免费获取和安装的方法TLS SSL 证书 从而在 Web 服务器上启用加密的 HTTPS 它通过提供软件客户端简化了流程 Certbot 它尝试自动化大多数 如果不是全部 所需
  • 如何在 CentOS 6 上安装 Linux、Apache、MySQL、PHP (LAMP) 堆栈

    Status 已弃用 本文介绍不再受支持的 CentOS 版本 如果您当前运行的服务器运行 CentOS 6 我们强烈建议您升级或迁移到受支持的 CentOS 版本 Reason CentOS 6 于 2020 年 11 月 30 日达到生
  • 如何在 Ubuntu 16.04 上安装 Docker Compose

    介绍 Docker是一个很好的工具 用于在软件容器内自动部署 Linux 应用程序 但要充分利用其潜力 应用程序的每个组件都应该在自己的单独容器中运行 对于具有大量组件的复杂应用程序 编排所有容器一起启动 通信和关闭可能很快就会变得笨拙 D
  • 如何在 Ubuntu 12.04 上安装 IonCube Loader

    Status 已弃用 本文介绍不再受支持的 Ubuntu 版本 如果您当前运行的服务器运行 Ubuntu 12 04 我们强烈建议您升级或迁移到受支持的 Ubuntu 版本 升级到Ubuntu 14 04 从 Ubuntu 14 04 升级
  • 如何在 Ubuntu 12.04 上安装 Git

    Status 已弃用 本文介绍不再受支持的 Ubuntu 版本 如果您当前运行的服务器运行 Ubuntu 12 04 我们强烈建议您升级或迁移到受支持的 Ubuntu 版本 升级到Ubuntu 14 04 从 Ubuntu 14 04 升级
  • Android 日期时间选择器对话框

    Android 日期时间选择器在 Android 应用程序中被大量使用 在本教程中 我们将演示如何使用日期选择器 and 定时器选择器我们的 Android 应用程序中的对话框 这些组件用于在自定义用户界面中选择日期和时间 我们将使用Dat
  • 如何将 GitLab 设置为您自己的私有 GitHub 克隆

    Status 已弃用 本文介绍不再受支持的 Ubuntu 版本 如果您当前运行的服务器运行 Ubuntu 12 04 我们强烈建议您升级或迁移到受支持的 Ubuntu 版本 升级到Ubuntu 14 04 从 Ubuntu 14 04 升级
  • Java 中的关系运算符

    Java 中的关系运算符用于比较两个变量的相等 不相等 大于 小于等 Java 关系运算符始终返回布尔值 true 或 false Java 中的关系运算符 Java 有 6 个关系运算符 是相等运算符 如果两个操作数引用同一个对象 则返回
  • 约束布局使用详解

    约束布局使用详解 一 前言 在一般的安卓开发中 编写界面需要很多嵌套 这会有一定的性能影响 这个时候就可以使用 ConstraintLayout 或 RelativeLayout来减少嵌套 简化布局深度 ConstraintLayot 类似
  • PowerShell: 关于比较运算符返回值

    Windows PowerShell的比较运算符包括 eq ne lt gt le ge contains notcontains like notlike match notmatch replace 大部分的比较运算符返回一个布尔值 比
  • java 中 next() 与 nextLine() 方法的区别

    在说它俩的不同之处前 先说说它俩的相同之处 next 和 nextLine 读取的结果都是 String 类型 返回 string 类型 java 中 Scanner 类中的 next 方法和 nextLine 方法的区别 next 不会读
  • 软件设计分为结构化设计(SD)

    软件设计分为结构化设计 SD 与面向对象设计 OOD 其中结构化设计SD是一种面向数据流的方法 它以SRS 软件需求规格说明书 和SA 结构化分析 阶段所产生的和数据字典等文档为基础 是一个自顶向下 逐步求精和模块化的过程 SD方法的基本思
  • linq.js文档

    Linqjs User Documentation
  • Python程序员如何制定学习计划?提高编写代码的能力

    在工作和生活压力之下 如何提升自己的技能和能力 这是许多人都面临的问题 如果你也有这样的问题 那么首先要明确的是 要想提升自己的能力 必须要有一个清晰的计划和方向 这个计划可以是长期的 也可以是短期的 但必须要有一个大的方向性 接下来 我们
  • 解决no tracked branch的问题,并详说远程分支、远程跟踪分支和跟踪分支【本地分支】

    目录 问题 分支 远程分支 远程跟踪分支 跟踪分支 什么是跟踪分支 设置跟踪分支 跟踪分支的作用 iss53分支 master分支 serverfix分支 testing分支 定位问题 解决问题 问题 今天我准备从git代码库中更新代码到我
  • presto 0.166概述

    presto是什么 是Facebook开源的 完全基于内存的并 计算 分布式SQL交互式查询引擎 是一种Massively parallel processing MPP 架构 多个节点管道式执 持任意数据源 通过扩展式Connector组
  • Unity的C#编程教程_53_类 Class 详解及应用练习(二)

    文章目录 Class Inheritence 1 Class Inheritence 2 Bank System Inheritance Example Protected Data Members Virtual Methods and
  • k8s中安装kubesphere、kuboard、rancher记录

    首先需要安装好k8s集群 参考链接 版本号可以根据自己需求变更 安装kubesphere 参考链接 直接执行命令即可 很方便 一般安装不成功是因为镜像pull不下来 可以执行kubectl describe pod xxx n kubesp
  • 个人笔记--FreeRTOS事件标志组

    FreeRTOS事件标志组 简介 事件的基本概念 事件是一种实现任务间通信的机制 主要用于实现任务间的同步 与信号量不同的是 事件通信只能传输事件是否发生 不能传递数据 而且事件可以实现一对多 多对多的同步 一个任务可以等待多个事件的发送