16.事件标志组

news2024/11/25 14:54:56

一、简介

事件标志组与信号量一样属于任务间同步的机制,但是信号量一般用于任务间的单事件同
步,对于任务间的多事件同步,仅使用信号量就显得力不从心了。FreeRTOS 提供的事件标志组
可以很好的处理多事件情况下的任务同步。

1. 事件标志

事件标志是一个用于指示事件是否发生的布尔值,一个事件标志只有 0 或 1 两种状态,
FreeRTOS 将多个事件标志储存在一个变量类型为 EventBits_t 变量中,这个变量就是事件组。

2. 事件组

事件组是一组事件标志的集合,一个事件组就包含了一个 EventBites_t 数据类型的变量,
变量类型 EventBits_t 的定义如下所示:

typedef TickType_t EventBits_t;
#if ( configUSE_16_BIT_TICKS == 1 )
 typedef uint16_t TickType_t;
#else
 typedef uint32_t TickType_t;
#endif
#define configUSE_16_BIT_TICKS 0

从上面可以看出,EventBits_t 实际上是一个 16 位或 32 位无符号的数据类型。当
configUSE_16_BIT_TICKS 配置为 0 时,EventBits_t 是一个 32 位无符号的数据类型;当
configUSE_16_BIT_TICKS 配置为 1 时,EventBits_t 是一个 16 为无符号的数据类型。在本套教程的所有配套例程中,都将配置项 configUSE_16_BIT_TICKS 配置为 0,因此本文就以
EventBits_t 为 32 位无符号数据类型为例进行讲解,对于另外一种情况,也是大同小异的。

虽然说使用了 32 位无符号的数据类型变量来存储事件标志,但这并不意味着,一个
EventBits_t 数据类型的变量能够存储 32 个事件标志,FreeRTOS 将这个 EventBits_t 数据类型的变量拆分成两部分,其中低 24 位[23:0](configUSE_16_BIT_TICKS 配置位 1 时,是低 8 位[7:0])用于存储事件标志,而高 8 位[31:24](configUSE_16_BIT_TICKS 配置位 1 时,依然是高 8 位[15:8])用作存储事件标志组的一些控制信息,也就是说一个事件组最多可以存储 24 个事件标志。EventBits_t 数据类型变量的位使用情况如下图所示:
在这里插入图片描述
从上图中可以看到,变量中低 24 位中的每一位都是一个事件标志,当某一位被置一时,就
表示这一位对应的事件发生了。

特点
在这里插入图片描述

3.事件标志组与队列、信号量的区别

在这里插入图片描述

二、相关 API 函数

在这里插入图片描述

1. 创建事件标志组

FreeRTOS 提供了两种创建事件标志组的方式,分别为动态方式创建事件标志组和静态方式创建事件标志组,两者的区别在于静态方式创建事件标志组时,需要用户提供创建事件标志组所需的内存空间,而使用动态方式创建事件标志组时,FreeRTOS 会自动从 FreeRTOS 管理的
堆中分配创建事件标志组所需的内存空间。
动态方式创建事件标志组 API 函数的函数原型如下所示:

EventGroupHandle_t xEventGroupCreate(void);

在这里插入图片描述
静态方式创建事件标志组 API 函数的函数原型如下所示:

EventGroupHandle_t xEventGroupCreateStatic(StaticEventGroup_t * pxEventGroupBuffer);

在这里插入图片描述

2. 删除事件标志组

FreeRTOS 提供了用于删除事件标志组的 API 函数,函数原型如下所示:

void vEventGroupDelete(EventGroupHandle_t xEventGroup);

在这里插入图片描述

3. 等待事件标志位

等待事件标志位使用的是函数 xEventGroupWaitBits(),其函数原型如下所示:

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

在这里插入图片描述

4. 设置事件标志位

FreeRTOS 提供了两个用于设置事件标志位的 API 函数,这个两个函数分别用于在任务和
在中断中设置事件标志位。
在任务中设置事件标志位 API 函数的函数原型如下所示:

EventBits_t xEventGroupSetBits(
 EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToSet)

在这里插入图片描述
在中断中设置事件标志位 API 函数的函数原型如下所示:

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

在这里插入图片描述

5. 清零事件标志位

FreeRTOS 提供了两个用于清零事件标志位的 API 函数,这个两个函数分别用于在任务和
在中断中清零事件标志位。
在任务中清零事件标志位 API 函数的函数原型如下所示:

EventBits_t xEventGroupClearBits(
 EventGroupHandle_t xEventGroup,
 const EventBits_t uxBitsToClear)

在这里插入图片描述
在这里插入图片描述

6. 获取事件组中事件标志位的值

FreeRTOS 提供了两个用于获取事件组中事件标志位值的 API 函数,这个两个函数分别用
于在任务和在中断中获取事件组中事件标志位的值。
在任务中获取事件组中事件标志位值 API 函数的函数原型如下所示:

EventBits_t xEventGroupGetBits(xEventGroup);

在这里插入图片描述

7. 函数 xEventGroupSync()

此函数一般用于多任务同步,其中每个任务都必须等待其他任务达到同步点,然后才能继续执行。函数 xEventGroupSync()的函数原型如下所示:

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

在这里插入图片描述

三、相关实验

在这里插入图片描述

#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
#include "./MALLOC/malloc.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
/******************************************************************************************************/
/*FreeRTOS配置*/

/* START_TASK 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

/* TASK1 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK1_PRIO         2
#define TASK1_STACK_SIZE   128
TaskHandle_t    task1_handler;
void task1( void * pvParameters );


/* TASK2 任务 配置
 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务
 */
#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );

/******************************************************************************************************/
EventGroupHandle_t  eventgroup_handle;
#define EVENTBIT_0  (1 << 0)
#define EVENTBIT_1  (1 << 1)
/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */
void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
    eventgroup_handle = xEventGroupCreate();
    if(eventgroup_handle != NULL)
    {
        printf("事件标志组创建成功!!\r\n");
    }
    
    xTaskCreate((TaskFunction_t         )   task1,
                (char *                 )   "task1",
                (configSTACK_DEPTH_TYPE )   TASK1_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK1_PRIO,
                (TaskHandle_t *         )   &task1_handler );
                
    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
                             
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}

/* 任务一,释放二值信号量 */
void task1( void * pvParameters )
{
    uint8_t key = 0;
    while(1) 
    {
        key = key_scan(0);
        if(key == KEY0_PRES)
        {
            xEventGroupSetBits( eventgroup_handle, EVENTBIT_0); /* 将事件标志组的bit0位置1 */
        }else if(key == KEY1_PRES)
        {
            xEventGroupSetBits( eventgroup_handle, EVENTBIT_1); /* 将事件标志组的bit1位置1 */
        }
        vTaskDelay(10);
    }
}

/* 任务二,获取二值信号量 */
void task2( void * pvParameters )
{
    EventBits_t event_bit = 0;
    while(1)
    {
        event_bit = xEventGroupWaitBits( eventgroup_handle,         /* 事件标志组句柄 */
                                         EVENTBIT_0 | EVENTBIT_1,   /* 等待事件标志组的bit0和bit1位 */
                                         pdTRUE,                    /* 成功等待到事件标志位后,清除事件标志组中的bit0和bit1位 */
                                         pdTRUE,                    /* 等待事件标志组的bit0和bit1位都置1,就成立 */
                                         portMAX_DELAY );           /* 死等 */
        printf("等待到的事件标志位值为:%#x\r\n",event_bit);
    }
}

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

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

相关文章

C语言文件操作2

1.二进制读写函数 在上一章我们介绍了字符读写函数、文本读写函数和格式化输入输出函数&#xff0c;这张我们继续为大家介绍剩下的一组读写函数——二进制读写函数&#xff1a;fread函数和fwrite函数。 ⚀fread函数 &#x1f7e1;函数作用 以二进制的方式从指定流中读取数据 …

Nuxt3 实战 (三):使用 release-it 自动管理版本号和生成 CHANGELOG

release-it 能做什么&#xff1f; 增加版本号并提交 Git生成变更日志&#xff08;Changelog&#xff09;并提交到 Git创建 Git 标签并推送到远程仓库发布到 npm 等软件仓库在 GitHub、GitLab 等平台创建发行版 前置知识 在看这篇文章之前&#xff0c;我们有必要了解一下 Sem…

Java 那些诗一般的 数据类型 (下篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能接…

SpringBoot整合RabbitMQ-应答模式

一、应答模式 RabbitMQ 中的消息应答模式主要包括两种&#xff1a;自动应答&#xff08;Automatic Acknowledgement&#xff09;和手动应答&#xff08;Manual Acknowledgement&#xff09;。&#xff08;一般交换机发送消息&#xff0c;RabbitMQ只有在接收到消费者的确认后才…

【鸿蒙开发】ArkTS和组件

1. 初识ArkTS语言 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性。 当前&#xff0c;ArkTS在TS的基础上主要扩展了如下能力&#xff1a; 基本语法&#xff1a;ArkTS定义了声明式UI描述、自…

终端进程“CWindowsSystem32WindowsPowerShellv1.0powershell.exe”已终止,退出代码 2。

终端进程“C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe”已终止&#xff0c;退出代码: 2。 今天安装了最新版的VScode&#xff0c;果然&#xff0c;出毛病了 在我每次运行终端运行vue3项目时&#xff0c;只要主动CtrlC退出&#xff0c;终端就会闪退&#xff…

2024洗地机哪个牌子好?六大避坑攻略总结

洗地机就像是吸尘器和电动拖把的结合体&#xff0c;对于每天要做家务的人来说&#xff0c;可以一次性解决多种类型的垃圾&#xff0c;省时省心省力。但是面对种类繁重的洗地机市场&#xff0c;大家时常会无从下手&#xff0c;今天笔者就给大家总结了六大洗地机避坑指南。 洗地…

购买了Hostease的企业邮箱服务后如何启用

最近有遇到客户购买了Hostease的企业邮箱后不知道该如何去启用的问题&#xff0c;这里我们简单分享一下Hostease的企业邮箱购买到使用的操作。 Hostease提供了两种邮箱服务套餐选择&#xff0c;OX App Suite和OX App Suite Productivity&#xff0c;OX App Suite Productivi…

Agent——客服机器人(大模型+本地数据/话术+在线数据库)

我们先来介绍一下&#xff0c;这个客服机器人的特点&#xff0c;根据本地资料&#xff0c;回答用户问题&#xff0c;告别传统机器人的答非所问&#xff0c;同时根据用户回答&#xff0c;判断用户意向度&#xff0c;并询问感兴趣用户的个人信息&#xff0c;获得后&#xff0c;保…

【面试题】如何在级别用户中检查用户名是否存在?

前言 不知道大家有没有留意过&#xff0c;在使用一些app或者网站注册的时候&#xff0c;提示你用户名已经被占用了&#xff0c;比如我们熟知的《英雄联盟》有些人不知道取啥名字&#xff0c;干脆就叫“不知道取啥名”。 但是有这样困惑的可不止他一个&#xff0c;于是就出现了…

关于pandas 无法读取 csv 文件数据的解决方式

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 …

Golang笔记(下)

Golang学习笔记&#xff08;下&#xff09; 前篇&#xff1a;Golang学习笔记(上) 十四、错误处理 14.1使用error类型 func New(text string) error例子&#xff1a; package mainimport ("errors" // 导入errors包"fmt" )func main() {var number, divi…

网页版五子棋对战实现和自动化测试

文章目录 前言一、项目描述项目演示链接 二、实现的功能与操作1.登录注册2.游戏大厅线程安全问题多开处理 3.五子棋对战 三、项目测试1.测试用例2.测试技术点3.部分测试用例展示&#xff08;1&#xff09;注册页面&#xff08;2&#xff09;登录页面&#xff08;3&#xff09;游…

ChatGPT与生成式AI:教育领域内新的浪潮与挑战

随着ChatGPT和其他生成式AI技术&#xff0c;如GPT-3.5、GPT-4的出现&#xff0c;我们正见证教育领域一场前所未有的变革浪潮。这些技术不仅推动了教育方式的进步&#xff0c;也为学习者带来了全新的机遇和挑战。 NO.1教育变革的新浪潮 生成式AI技术&#xff0c;特别是ChatGPT&…

【Nature Electronics】二维钙钛矿氧化物SNO作为high-κ栅介质的应用

【Li, S., Liu, X., Yang, H. et al. Two-dimensional perovskite oxide as a photoactive high-κ gate dielectric. Nat Electron 7, 216–224 (2024). https://doi.org/10.1038/s41928-024-01129-9】 概括总结&#xff1a; 本研究探讨了二维钙钛矿氧化物Sr2Nb3O10&#xf…

我们有了统一的Domino应用市场

大家好&#xff0c;才是真的好。 和大家一样&#xff0c;刚休假回来就发现HCL又上新了。这回是个大消息&#xff0c;直接上了一个Notes/Domino应用市场&#xff0c;地址是https://hclsofy.com/domino。 截至本篇写作时&#xff0c;提交到该市场的Notes/Domino相关扩展工具和应…

ATM04-6P 安费诺汽车连接器6芯压线端子胶壳

ATM04-6P是一款压线端子胶壳&#xff0c;属于Amphenol&#xff08;安费诺&#xff09;品牌 ATM04-6P 规格信息&#xff1a; 制造商:Amphenol 产品种类:汽车连接器 RoHS:是 产品:Connectors 位置数量:6 Position 型式:Receptacle (Female) 线规量程:22 AWG to 16 AWG 系列:ATM 颜…

layui后台框架,将左侧功能栏目 集中到一个页面,通过上面的tab切换 在iframe加载对应页面

实现上面的 功能效果。 1 html代码 <form class"layui-form layui-form-pane" action""><div class"layui-tab" lay-filter"demo"><ul class"layui-tab-title"><li id"a0" class"lay…

常见的mq产品和优点

常见的mq产品和优点 一、什么是mq? MQ全称 Message Queue&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信&#xff0c;解耦。 二、常见的mq产品 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMq …

基于51单片机轮胎胎压监测系统—数码管显示

基于51单片机轮胎胎压监测系统 &#xff08;仿真&#xff0b;程序&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.MPX4115压力传感器胎压检测&#xff1b; 2.ADC0832进行模数转换后&#xff0c;51单片机处理控制&#xff1b; 3.数码管显示胎压&#xff…