RT-Thread事件集

举报
yd_274589494 发表于 2024/05/26 08:18:43 2024/05/26
【摘要】 @TOC 前言本篇文章将给大家讲解RT-Thread中事件集的概念,了解什么是事件集及事件集的函数使用方法。 一、RT-Thread事件集的概念事件集是一种用于线程间通信的同步对象,它通常用于实现线程之间的事件触发、通知和等待。在RT-Thread中,事件集是由struct rt_event结构体表示的,该结构体定义在rtthread.h头文件中。事件集可以包含多个事件标志位,每个标志位可以...

@TOC


前言

本篇文章将给大家讲解RT-Thread中事件集的概念,了解什么是事件集及事件集的函数使用方法。

一、RT-Thread事件集的概念

事件集是一种用于线程间通信的同步对象,它通常用于实现线程之间的事件触发、通知和等待。在RT-Thread中,事件集是由struct rt_event结构体表示的,该结构体定义在rtthread.h头文件中。事件集可以包含多个事件标志位,每个标志位可以表示一个事件。事件集的操作包括设置事件、清除事件、等待事件以及获取事件等。

在这里插入图片描述
每个线程都有一个 rt_thread 结构体,它里面有如下 2 个成员:

struct rt_thread
{
 ......
##if defined(RT_USING_EVENT)
 /* thread event */
 rt_uint32_t event_set;
 rt_uint8_t event_info;
##endif
 ......
}

这两个成员的作用如下:

event_set:想等待哪些事件?
可以设置对应的位,比如设置为(1<<30) | (1<<0)表示等待事件 0、事件 30那么,它想等待事件 0、事件 30 都发生呢,还是只要事件 0、事件 30 任意一个发生即可?需要使用 event_info 进一步描述

event_info:有 3 种取值
RT_EVENT_FLAG_AND:逻辑与,比如事件 0、事件 30 都发生时,才满足它的期待RT_EVENT_FLAG_OR:逻辑或,比如事件 0、事件 30 发生了任何一个,都满足它的期待 RT_EVENT_FLAG_CLEAR:等到期待的事件后,是否清除事件

二、事件集函数的使用

1.创建事件集函数

rt_event_t rt_event_create(const char name, rt_uint8_t flag)

功能:创建一个事件集。

参数:
const char* name:事件集的名称,用于标识该事件集。
rt_uint8_t flag:事件集的初始标志位,用于指定初始的事件状态。

返回值:返回一个rt_event_t类型的事件集对象,如果创建失败则返回RT_NULL。

说明:该函数用于创建一个事件集对象,并返回该对象的句柄。可以使用该句柄对事件集进行操作,如设置事件、清除事件等。

rt_err_t rt_event_init(rt_event_t event, const char name, rt_uint8_t flag)

功能:初始化一个已经存在的事件集。

参数:
rt_event_t event:要初始化的事件集对象。
const char* name:事件集的名称,用于标识该事件集。
rt_uint8_t flag:事件集的初始标志位,用于指定初始的事件状态。

返回值:初始化成功返回RT_EOK,否则返回相应的错误码。
说明:该函数用于初始化一个已经存在的事件集对象,可以重新设置事件集的名称和初始状态。

2.事件集发送函数

rt_err_t rt_event_send(rt_event_t event, rt_uint32_t set):

功能:设置事件集的事件标志位。
参数:

rt_event_t event:要操作的事件集对象。

rt_uint32_t set:要设置的事件标志位,可以设置多个事件。

返回值:设置成功返回RT_EOK,否则返回相应的错误码。
说明:该函数用于设置事件集的事件标志位,表示某些事件已经发生。

3.事件集接收函数

rt_err_t rt_event_recv(rt_event_t event, rt_uint32_t set, rt_uint8_t option, rt_int32_t timeout, rt_uint32_t recved)**:

功能:等待事件集的事件发生。
参数:

rt_event_t event:要等待的事件集对象。

rt_uint32_t set:指定要等待的事件标志位,可以等待多个事件。

rt_uint8_t option:等待选项,例如等待所有指定的事件发生还是只要有一个事件发生。

rt_int32_t timeout:超时时间,单位为毫秒,若为RT_WAITING_FOREVER则表示永久等待,若为RT_WAITING_NO则表示不等待。

rt_uint32_t* recved:指向一个变量的指针,用于存储实际接收到的事件标志位。

返回值:等待成功返回RT_EOK,否则返回相应的错误码。

说明:该函数用于等待事件集中指定的事件标志位发生,如果指定的事件发生,则将实际接收到的事件标志位存储在recved参数中。

4.事件集删除函数

rt_err_t rt_event_delete(rt_event_t event):

功能:删除一个事件集。
参数:

rt_event_t event:要删除的事件集对象。

返回值:删除成功返回RT_EOK,否则返回相应的错误码。

说明:该函数用于删除一个事件集对象,释放相关资源。

rt_err_t rt_event_detach(rt_event_t event):

功能:解绑一个事件集,不再使用它。
参数:

rt_event_t event:要解绑的事件集对象。

返回值:解绑成功返回RT_EOK,否则返回相应的错误码。

说明:该函数用于解绑一个事件集对象,但不会删除它,可以用于释放对事件集的引用而不影响其状态。

三、事件集使用例程

#include <stdio.h>
#include <rtthread.h>

#define EVENT_A (1 << 0)
#define EVENT_B (1 << 1)

int main(void) {
    // 创建一个事件集
    rt_event_t event = rt_event_create("my_event", RT_IPC_FLAG_PRIO);
    if (event == RT_NULL) {
        printf("Failed to create event\n");
        return -1;
    }

    // 设置事件A
    rt_event_send(event, EVENT_A);
    printf("Event A has occurred\n");

    // 设置事件B
    rt_event_send(event, EVENT_B);
    printf("Event B has occurred\n");

    // 等待事件A和事件B同时发生
    rt_uint32_t recved = 0;
    rt_err_t result = rt_event_recv(event, EVENT_A | EVENT_B, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);
    if (result == RT_EOK) {
        printf("Both event A and event B have occurred\n");
    } else {
        printf("Failed to wait for events\n");
    }

    // 等待事件A发生
    result = rt_event_recv(event, EVENT_A, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);
    if (result == RT_EOK) {
        printf("Event A has occurred\n");
    } else {
        printf("Failed to wait for event A\n");
    }

    // 删除事件集
    rt_event_delete(event);

    return 0;
}

总结

本篇文章主要就是讲解了事件集大家可以对比和FreeRTOS中的事件集,并且自己写代码进行实践。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。