文章目录
- 前言
- 一、RT-Thread事件集的概念
- 二、事件集函数的使用
- 1.创建事件集函数
- 2.事件集发送函数
- 3.事件集接收函数
- 4.事件集删除函数
- 三、事件集使用例程
- 总结
前言
本篇文章将给大家讲解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中的事件集,并且自己写代码进行实践。