FreeRTOS学习 -- 事件标志组

news2024/11/18 19:33:01

一、事件标志组简介

1、事件位(事件标志)

事件位用来表明某个事件是否发生,事件位通常用作事件标志,比如下面的几个例子:

  • 当收到一条消息并且把这条消息处理掉以后就可以将某个位(标志)置1,当队列中没有消息需要处理的时候就可以将这个位(标志)置0。
  • 当把队列中的消息通过网络发送输出以后就可以将某个位(标志)置1,当没有数据需要从网络发送出去的话就将这个位(标志)置0。
  • 现在需要向网络中发送一个心跳信息,将某个位(标志)置1,现在不需要向网络中发送心跳信息,这时候将这个位(标志)置0。

2、事件组

一个事件组就是一组事件位,事件组中的事件位通过位编号来访问,举个栗子:

  • 事件标志组的 bit0 表示队列中的消息是否处理掉。
  • 事件标志组的 bit1 表示是否有消息需要从网络中发送出去。
  • 事件标志组的 bit2 表示现在是否需要向网络发送心跳信息。

3、事件标志组和事件位的数据类型

事件标志组的数组类型为 EventGroupHandle_t,当 configUSE_16_BIT_TICKS 为 1 的时候事件标志组可以存储 8 个事件位,当 configUSE_16_BIT_TICKS 为 0 的时候事件标志组存储 24个事件位。
事件标志组中的所有事件位都存储在一个无符号的 EventBits_t 类型的变量中,EventBits_t 在 event_groups.h 中有如下定义:

typedef	TickType_t	EventBits_t;	

数据类型 TickType_t 在文件 portmacro.h 中有如下定义:

#if( configUSE_16_BIT_TICKS == 1 ) typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff #else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL #define portTICK_TYPE_IS_ATOMIC 1
#endif

当 configUSE_16_BIT_TICKS 为 0 的时候 TickType_t 是个 32 位的数据类型,因此 EventBits_t 也是个 32 位的数据类型。EventBits_t 类型的变量可以存储 24 个事件位,另外的那高 8 位有其他用。事件位 0 存放在这个变量的 bit0 上,变量的 bit1 就是事件位 1,以此类推。对于 STM32 来说一个事件标志组最多可以存储 24 个事件位。
在这里插入图片描述

二、创建事件标志组

FreeRTOS 提供了两个用于创建事件标志组的函数。
在这里插入图片描述

1、函数 xEventGroupCreate()

此函数用于创建一个事件标志组,所需要的内存通过动态内存管理方法分配。由于内部处理的原因,事件标志组可用 bit 数取决于 configUSE_16_BIT_TICKS ,当 configUSE_16_BIT_TICKS1 为 1 的时候事件标志组有 8 个可用的位(bit0~ bit7) ,当 configUSE_16_BIT_TICKS 为 0 的时候事件标志组有 24 个可用的位(bit0~bit23)。

EventGroupHandle_t xEventGroupCreate( void )

参数:
无。

返回值:

  • NULL: 事件标志组创建失败。
  • 其他值: 创建成功的事件标志组句柄。

2、函数 xEventGroupCreateStatic()

此函数用于创建一个事件标志组定时器,所需要的内存需要用户自行分配。

EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )

参数:

  • pxEventGroupBuffer: 参数指向一个 StaticEventGroup_t 类型的变量,用来保存事件标志组结构体。

返回值:

  • NULL: 事件标志组创建失败。
  • 其他值: 创建成功的事件标志组句柄。

三、设置事件位

FreeRTOS 提供了 4 个函数用来设置事件标志组中事件位(标志),事件位(标志)的设置包括清零和置1。
在这里插入图片描述

1、函数 xEventGroupClearBits()

将事件标志组中的指定事件位清零,此函数只能用在任务中,不能用在中断服务函数中。

EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
const EventBits_t	uxBitsToClear );

参数:

  • xEventGroup: 要操作的事件标志组的句柄。
  • uxBitsToClear: 要清零的事件位,比如要清除 bit3 的话就设置为 0X08。可以同时清除多个bit,如设置为 0X09 的话就是同时清除 bit3 和 bit0。

返回值:

  • 任何值: 将指定事件位清零之前的事件组值。

2、函数 xEventGroupClearBitsFromISR()

此函数为函数 xEventGroupClearBits()的中断级版本,也是将指定的事件位(标志)清零。此函数用在中断服务函数中,此函数原型如下:

BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t	xEventGroup,
const EventBits_t	uxBitsToSet );

参数:

  • xEventGroup: 要操作的事件标志组的句柄。
  • uxBitsToClear: 要清零的事件位,比如要清除 bit3 的话就设置为 0X08。可以同时清除多个bit,如设置为 0X09 的话就是同时清除 bit3 和 bit0。

返回值:

  • pdPASS: 事件位清零成功。
  • pdFALSE: 事件位清零失败。

3、函数 xEventGroupSetBits()

设置指定的事件位为 1,此函数只能用在任务中,不能用于中断服务函数,此函数原型如下:

EventBits_t xEventGroupSetBits( EventGroupHandle_t	xEventGroup,
const EventBits_t	uxBitsToSet );

参数:

  • xEventGroup: 要操作的事件标志组的句柄。
  • uxBitsToClear: 指定要置 1 的事件位,比如要将 bit3 值 1 的话就设置为 0X08。可以同时将多个 bit 置 1,如设置为 0X09 的话就是同时将 bit3 和bit0 置 1。

返回值:

  • 任何值: 在将指定事件位置 1 后的事件组值。

3、函数 xEventGroupSetBitsFromISR()

此函数也用于将指定的事件位置 1,此函数是 xEventGroupSetBits()的中断版本,用在中断服务函数中,函数原型如下:

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

参数:

  • xEventGroup: 要操作的事件标志组的句柄。
  • uxBitsToClear: 指定要置 1 的事件位,比如要将 bit3 值 1 的话就设置为 0X08。可以同时将多个 bit 置 1,如设置为 0X09 的话就是同时将 bit3 和bit0 置 1。
    pxHigherPriorityTaskWoken:标记退出此函数以后是否进行任务切换,这个变量的值函数会自动设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之前一定要进行一次任务切换。

返回值:

  • pdPASS: 事件位置 1 成功。
  • pdFALSE: 事件位置 1 失败。

四、获取事件标志组值

FreeRTOS 提供的两个 API 函数来查询事件标准组值。
在这里插入图片描述

1、函数 xEventGroupGetBits()

此函数用于获取当前事件标志组的值,也就是各个事件位的值。此函数用在任务中,不能用在中断服务函数中。此函数是个宏,真正执行的是函数 xEventGroupClearBits(),函数原型如下:

EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup )	

参数:

  • xEventGroup: 要获取的事件标志组的句柄。

返回值:

  • 任何值:当前事件标志组的值。

2、函数 xEventGroupGetBitsFromISR()

获取当前事件标志组的值,此函数是 xEventGroupGetBits()的中断版本,函数原型如下:

EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )	

参数:

  • xEventGroup: 要获取的事件标志组的句柄。

返回值:

  • 任何值: 当前事件标志组的值。

五、等待指定的事件位

某个任务可能需要与多个事件进行同步,那么这个任务就需要等待并判断多个事件位(标志),使用函数 xEventGroupWaitBits()可以完成这个功能。调用函数以后如果任务要等待的事件位还没有准备好(置1或清零)的话任务就会进入阻塞态,直到阻塞时间到达或者所等待的事件位准备好。

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

参数:

  • xEventGroup: 指定要等待的事件标志组。
  • uxBitsToWaitFord:指定要等待的事件位,比如要等待bit0 和(或)bit2 的时候此参数就是0X05,如果要等待 bit0 和(或)bit1 和(或)bit2 的时候此参数就是 0X07,以此类推。
  • xClearOnExit: 此参数要是为pdTRUE 的话,那么在退出此函数之前由参数uxBitsToWaitFor所设置的这些事件位就会清零。如果设置位 pdFALSE 的话这些事件位就不会改变。
  • xWaitForAllBits: 此参数如果设置为 pdTRUE 的话,当 uxBitsToWaitFor 所设置的这些事件位都置 1,或者指定的阻塞时间到的时候函数 xEventGroupWaitBits()才会返回。当此函数为 pdFALSE 的话,只要 uxBitsToWaitFor 所设置的这些事件位其中的任意一个置 1 ,或者指定的阻塞时间到的话函数 xEventGroupWaitBits()就会返回。
  • xTicksToWait: 设置阻塞时间,单位为节拍数。

返回值:

  • 任何值: 返回当所等待的事件位置 1 以后的事件标志组的值,或者阻塞时间到。根据这个值我们就知道哪些事件位置 1 了。如果函数因为阻塞时间到而返回的话那么这个返回值就不代表任何的含义。

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

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

相关文章

阅读台灯什么品牌好?一文带你了解热门阅读台灯推荐

阅读台灯最终都绕不开护眼这个话题。护眼灯作为保护视力的辅助工具,以有效护眼的价值深受大众青睐。学生长时间用眼,普通台灯的伤害大,而阅读台灯的出现,通过其先进的技术和设计,能为学生提供了一个既舒适又健康的照明…

十三、代理模式

文章目录 1 基本介绍2 案例2.1 Sortable 接口2.2 BubbleSort 类2.3 SortTimer 类2.4 Client 类2.5 Client 类的运行结果2.6 总结 3 各角色之间的关系3.1 角色3.1.1 Subject ( 主体 )3.1.2 RealObject ( 目标对象 )3.1.3 Proxy ( 代理 )3.1.4 Client ( 客户端 ) 3.2 类图 4 动态…

vue3学习day04-provide和inject、defineOptions、defineModel、Pinia、pinia持久化

15、provide和inject (1)作用:顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信 (2)语法: 1)顶层组件通过provide函数提供数据 2)底层函数提供inject获取数据…

封装el-table 基于element封装可配置JSON表格组件

基于element封装可配置JSON表格组件 话不多说直接贴代码&#xff0c;复制运行即可查看效果 子组件全部代码 <template><div class"custom-table"><el-table:data"tableData"borderstyle"width: 100%"size"mini"max-h…

[AI绘画] 简明原生 ComfyUI 三重超细节放大教程(附工作流)

本教程将从0构建 ComfyUI 三重细节填充放大工作流&#xff0c;人有多大胆&#xff0c;图有多大产 **&#xff08;建议横屏&#xff09;**鬼灭之刃 堕姬 & 甘露寺蜜璃 三重细节填充放大 16K(154888832) 「四种放大」 ”潜空间“和”像素空间”&#xff0c;图像放大可…

精通C++ STL(三):vector的介绍及使用

目录 vector的介绍 vector的使用 vector的定义方式 vector的空间增长问题 size和capacity reserve和resize empty vector的迭代器使用 begin和end rbegin和rend vector的增删查改 push_back和pop_back insert和erase swap 元素访问 vector迭代器失效问题 迭代器失效问题举例 …

vue3+Vite实现滑动拼图验证

参考文档&#xff1a;https://github.com/javaLuo/vue-puzzle-vcode/blob/master/README3.md 最近想学习一下这个前端滑动拼图的实现&#xff0c;就找了一个第三方库&#xff0c;该库支持vue2和vue3两个版本&#xff0c;直接看文档就能上手&#xff0c;我自己跑了一边倒&#…

武汉流星汇聚:青少年为何钟情亚马逊?一站式购物与信任铸就魅力

在当今这个数字化时代&#xff0c;青少年的消费习惯正以前所未有的速度演变&#xff0c;他们不仅是未来的消费主力军&#xff0c;更是推动市场变革的重要力量。令人瞩目的是&#xff0c;Piper Sandler最新发布的青少年消费研究报告揭示了一个引人注目的现象&#xff1a;超过半数…

快速下载大模型的方法

现在&#xff0c;每天都有各种大模型不断涌现&#xff0c;这些模型文件通常都很大。如何快速又靠谱地下载这些开源大模型&#xff0c;放到我们的环境中&#xff0c;进行后续的微调、量化和部署工作呢&#xff1f;以下是我的一些经验分享。 准备 Docker 基础环境 首先&#xf…

个人知识库与RAG的技术

构建个人知识库时&#xff0c;采用RAG结合LangChain的方法极为有效。RAG&#xff0c;即检索增强生成技术&#xff0c;是一种前沿的自然语言处理手段&#xff0c;它融合了信息检索的精确匹配与语言模型的高效文本生成&#xff0c;为处理自然语言相关任务提供了一种既灵活又准确的…

java~泛型

目录 泛型 泛型的声明 泛型的实例化 泛型的使用细节 自定义泛型类 自定义泛型接口 自定义泛型方法 泛型的继承和通配符 Junit 单元测试类 泛型 检查添加元素的类型 减少了类型转换的次数&#xff0c;直接对这个类型进行遍历&#xff0c;例如arraylist<>() publ…

Python酷库之旅-第三方库Pandas(072)

目录 一、用法精讲 291、pandas.Series.dt.round函数 291-1、语法 291-2、参数 291-3、功能 291-4、返回值 291-5、说明 291-6、用法 291-6-1、数据准备 291-6-2、代码示例 291-6-3、结果输出 292、pandas.Series.dt.floor函数 292-1、语法 292-2、参数 292-3、…

贪吃蛇游戏的实现:C++ 控制台版

功能概述 控制蛇的移动&#xff1a;使用WASD键控制蛇的移动方向。随机生成食物&#xff1a;蛇吃到食物后&#xff0c;食物会在游戏区域内随机生成。显示分数&#xff1a;游戏中会显示当前分数。游戏结束条件&#xff1a;当蛇碰到自己或走出边界时&#xff0c;游戏结束并显示“…

从巴黎到乐清,奥运精神引领全民健身新风尚!

16位火炬手接力&#xff0c;乐清点燃全民健身新篇章&#xff01; 作者&#xff1a;华夏之音总监&#xff0f;李望 在巴黎奥运会如火如荼进行的第11天&#xff0c;中国体育代表团以22枚金牌的骄人战绩领跑金牌榜&#xff0c;每一枚金牌都闪耀着中华体育精神的璀璨光芒&#xff…

c++ 连接mysql

其实就是MYsql c语言的API #define _CRT_SECURE_NO_WARNINGS 1 #define HOST "192.168.226.1" #define USER "root" #define PASSWORD "123456" #define PORT 3066#include <iostream> #include <stdlib.h> #include <mysql.…

【北斗授时服务】NTP网络时间服务器 安徽京准智造

【北斗授时服务】NTP网络时间服务器 安徽京准智造 【北斗授时服务】NTP网络时间服务器 安徽京准智造 一、NTP网络时间服务器产品介绍&#xff1a; NTP网络时间服务器是针对计算机、自动化装置等进行校时而研发的高科技设备&#xff0c;该产品可从GPS卫星&#xff08;北斗卫星、…

数据采集工具之Canal

本文主要介绍canal采集mysql数据的tcp、datahub(kafka)模式如何实现 1、下载canal https://aliyun-datahub.oss-cn-hangzhou.aliyuncs.com/tools/canal.deployer-1.1.5-SNAPSHOT.tar.gz 2、TCP模式的实现 a、canal.properties 打开看看即可&#xff0c;不需要调整 ######…

蚁群求解旅行商问题(TSP)的MATLAB例程

程序概况 输入需要经过的节点坐标&#xff1a; 运行程序后&#xff0c;即可得到&#xff1a; 运行结果 左图为遍历各点的运动轨迹&#xff0c;最终会回到起点右图为平均距离&#xff08;红线&#xff09;和最短距离在迭代时的变化情况 源代码 代码下载链接如下&#xff1a…

【工具类】JAVA (Android Studio )+ JS 加密解密 AES + Base 64

JAVA &#xff08;Android Studio &#xff09; JS 加密解密 AES Base 64 前言JAVA 代码&#xff08;解密&#xff09;JS代码&#xff08;加密&#xff09; 前言 整个过程&#xff1a; JS 接口先用AES加密&#xff0c;然后加密内容转Base64 编码&#xff1b;JAVA进行Base64解…

虹科干货 | 如何确保干冰运输的安全和稳定?

在上篇文章中&#xff0c;我们介绍了液氮罐运输和存储温度监测解决方案&#xff0c;本文我们将会了解医药供应链中干冰运输和温度监测的关键要点。 干冰在医药行业的应用 干冰是固体二氧化碳&#xff0c;当表面温度为 -78.5℃时&#xff0c;一块冷冻的干冰会直接转变为气体&am…