03_rtthread_event_test

该文章介绍了RT-Thread实时操作系统中的事件管理机制,包括事件类型定义、事件接口及一个详细的事件使用示例。在示例中,有两个线程分别发送和接收事件,展示了如何初始化事件对象,以及线程如何等待和发送特定事件标志。

1.rtthread event typedef and macro

 2.rtthread event interface

 3.rtthread event demo test

/**

*******************************************************************************
*/
/* 包含头文件 ----------------------------------------------------------------*/	
#include "main.h"
#include "rtthread.h"

/* 私有类型定义 --------------------------------------------------------------*/

/* 私有宏定义 ----------------------------------------------------------------*/
#define	THREAD_PRIORITY		( 9 )
#define	THREAD_TIMESLICE	( 5 )

#define	EVENT_FLAG_03	( 1 << 3)
#define EVENT_FLAG_05	( 1 <<5 )

/* 私有变量 ------------------------------------------------------------------*/
static  struct rt_event event;

//ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t thread_recv_event_stack[1024];
static struct rt_thread thread_recv_event;

static rt_uint8_t thread_send_event_stack[1024];
static struct rt_thread thread_send_event;

/* 扩展变量 ------------------------------------------------------------------*/

/* 私有函数原形 --------------------------------------------------------------*/
static void thread_recv_event_entry(void *param);
static void thread_send_event_entry(void *param);

/* 函数体 --------------------------------------------------------------------*/
void event_sample_test(void)
{
	rt_err_t ret;
	ret = rt_event_init(&event,"event",RT_IPC_FLAG_PRIO);
	if(ret != RT_EOK)
	{
		rt_kprintf("event init failed!\n");
	}

	// initial the thread
	rt_thread_init(&thread_recv_event,
					"thread_recv_event",
					thread_recv_event_entry,
					RT_NULL,
					&thread_recv_event_stack[0],
					sizeof(thread_recv_event_stack),
					THREAD_PRIORITY-1,
					THREAD_TIMESLICE);	
	rt_thread_startup(&thread_recv_event);

	rt_thread_init(&thread_send_event,
					"thread_send_event",
					thread_send_event_entry,
					RT_NULL,
					&thread_send_event_stack[0],
					sizeof(thread_send_event_stack),
					THREAD_PRIORITY,
					THREAD_TIMESLICE);	
	rt_thread_startup(&thread_send_event);
}

static void thread_recv_event_entry(void *param)
{
	rt_uint32_t e;

	/*
        first time to receive event(s):
        EITHER Event3 OR Event5 happened can resume thread1
        and then clear conrresponding event(s)' flag
    */
	if(rt_event_recv(&event, 								// rt_event_t event
					(EVENT_FLAG_03 | EVENT_FLAG_05), 		// rt_uint32_t set
					RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,	// rt_uint8_t option 
					RT_WAITING_FOREVER, 					// rt_int32_t timeout
					&e) == RT_EOK)							//rt_uint32_t * recved
	{
		rt_kprintf("thread recv event: OR recv event 0x%x\n",e);
	}

	rt_kprintf("thread RECV: delay 1s to prepare the second event\n");
    rt_thread_mdelay(1000);

	/*
        second time to receive event(s):
        BOTH Event3 AND Event5 happened can resume thread1
        and then clear conrresponding event(s)' flag
    */
    if(rt_event_recv(&event, 									// rt_event_t event
					(EVENT_FLAG_03 | EVENT_FLAG_05), 			// rt_uint32_t set
					RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,	// rt_uint8_t option 
					RT_WAITING_FOREVER, 						// rt_int32_t timeout
					&e) == RT_EOK)								//rt_uint32_t * recved
	{
		rt_kprintf("thread recv event: AND recv event 0x%x\n",e);
	}
					
	rt_kprintf("thread RECV leave.\n");
    
}

static void thread_send_event_entry(void *param)
{
	rt_kprintf("thread SEND: send event3\n");
    rt_event_send(&event, EVENT_FLAG_03);
    rt_thread_mdelay(200);

    rt_kprintf("thread SEND: send event5\n");
    rt_event_send(&event, EVENT_FLAG_05);
    rt_thread_mdelay(200);

    rt_kprintf("thread SEND: send event3\n");
    rt_event_send(&event, EVENT_FLAG_03);
    rt_kprintf("thread SEND leave.\n");
}

4.rtthread event test demo

rtthread event test demo的测试效果如下图:

RT-Thread 是一个开源的实时操作系统(RTOS),广泛应用于嵌入式系统中。它提供了一套**标准化、类 POSIX 的 API 接口**,支持多线程、信号量、互斥锁、事件集、消息队列、定时器等机制,并兼容 FinSH 命令行 shell 和设备驱动模型。 以下是 **RT-Thread 标准接口** 的核心模块及其使用方式,适用于基于 RT-Thread 4.0+ 版本的开发(包括 Nano、Standard、Smart 等版本)。 --- ### ✅ 1. 线程管理(Thread Management) 创建和启动任务线程。 ```c #include <rtthread.h> #define THREAD_PRIORITY 25 #define THREAD_STACK_SIZE 1024 #define THREAD_TIMESLICE 5 static rt_thread_t tid1 = RT_NULL; /* 线程入口函数 */ static void thread_entry(void *parameter) { int count = 0; while (1) { rt_kprintf("Hello from thread %s: count = %d\n", rt_thread_self()->name, count++); rt_thread_mdelay(1000); // 延时 1 秒 } } /* 创建线程 */ int thread_sample_init(void) { tid1 = rt_thread_create("t1", thread_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); if (tid1 != RT_NULL) { rt_thread_startup(tid1); } return 0; } INIT_APP_EXPORT(thread_sample_init); // 自动初始化 ``` > - `rt_thread_create()`:动态创建线程 > - `rt_thread_startup()`:启动线程 > - `rt_thread_mdelay(ms)`:毫秒延时 --- ### ✅ 2. 信号量(Semaphore) 用于资源访问控制或同步。 ```c #include <rtthread.h> static struct rt_semaphore sem; static void producer_thread_entry(void *parameter) { while (1) { rt_kprintf("Producer: 发送信号\n"); rt_sem_release(&sem); // 释放信号量 rt_thread_mdelay(2000); } } static void consumer_thread_entry(void *parameter) { while (1) { rt_sem_take(&sem, RT_WAITING_FOREVER); // 永久等待 rt_kprintf("Consumer: 接收到信号\n"); } } int sem_sample_init(void) { rt_sem_init(&sem, "sem1", 0, RT_IPC_FLAG_FIFO); // 初始值为 0 rt_thread_t t1 = rt_thread_create("prod", producer_thread_entry, RT_NULL, 1024, 20, 10); rt_thread_t t2 = rt_thread_create("cons", consumer_thread_entry, RT_NULL, 1024, 21, 10); if (t1) rt_thread_startup(t1); if (t2) rt_thread_startup(t2); return 0; } INIT_COMPONENT_EXPORT(sem_sample_init); ``` > - `rt_sem_init()`:静态初始化信号量 > - `rt_sem_take()` / `rt_sem_release()`:获取与释放 --- ### ✅ 3. 互斥锁(Mutex) 用于保护共享资源,防止竞态条件。 ```c #include <rtthread.h> static struct rt_mutex mutex; static void mutex_thread_entry(void *parameter) { while (1) { rt_mutex_take(&mutex, RT_WAITING_FOREVER); rt_kprintf("线程 %s 获得互斥锁\n", rt_thread_self()->name); // 模拟临界区操作 rt_thread_mdelay(500); rt_kprintf("线程 %s 释放互斥锁\n", rt_thread_self()->name); rt_mutex_release(&mutex); rt_thread_mdelay(1000); } } int mutex_sample_init(void) { rt_mutex_init(&mutex, "mtex", RT_IPC_FLAG_FIFO); for (int i = 0; i < 2; i++) { char name[8]; rt_snprintf(name, sizeof(name), "th%01d", i); rt_thread_t tid = rt_thread_create(name, mutex_thread_entry, RT_NULL, 1024, 20 + i, 10); if (tid) rt_thread_startup(tid); } return 0; } INIT_COMPONENT_EXPORT(mutex_sample_init); ``` > ⚠️ 注意:不可在中断中使用 `rt_mutex_take()`。 --- ### ✅ 4. 消息队列(Message Queue) 实现线程间数据传递。 ```c #include <rtthread.h> #define MSG_MAX_LEN 64 static struct rt_messagequeue mq; typedef struct { char text[MSG_MAX_LEN]; int id; } msg_t; static void sender_thread_entry(void *parameter) { msg_t msg; int count = 0; while (1) { rt_sprintf(msg.text, "message-%d", count++); msg.id = count; if (rt_mq_send(&mq, &msg, sizeof(msg)) == RT_EOK) { rt_kprintf("发送消息: %s\n", msg.text); } rt_thread_mdelay(1000); } } static void receiver_thread_entry(void *parameter) { msg_t msg; while (1) { rt_err_t result = rt_mq_recv(&mq, &msg, sizeof(msg), RT_WAITING_FOREVER); if (result == RT_EOK) { rt_kprintf("接收消息: %s (ID=%d)\n", msg.text, msg.id); } } } int mq_sample_init(void) { rt_mq_init(&mq, "test_mq", RT_NULL, sizeof(msg_t), sizeof(msg_t)*4, RT_IPC_FLAG_FIFO); rt_thread_t t1 = rt_thread_create("send", sender_thread_entry, RT_NULL, 1024, 20, 10); rt_thread_t t2 = rt_thread_create("recv", receiver_thread_entry, RT_NULL, 1024, 21, 10); if (t1) rt_thread_startup(t1); if (t2) rt_thread_startup(t2); return 0; } INIT_COMPONENT_EXPORT(mq_sample_init); ``` > - `rt_mq_init()`:初始化静态消息队列 > - `rt_mq_send()` / `rt_mq_recv()`:发送/接收固定长度消息 --- ### ✅ 5. 定时器(Timer) 支持单次和周期性定时任务。 ```c #include <rtthread.h> static void timer_timeout(void *parameter) { rt_kprintf("定时器触发! 参数: %s\n", (char*)parameter); } int timer_sample_init(void) { rt_timer_t timer = rt_timer_create("tmr1", timer_timeout, "hello", rt_tick_from_millisecond(1000), RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER); if (timer != RT_NULL) { rt_timer_start(timer); } return 0; } INIT_COMPONENT_EXPORT(timer_sample_init); ``` > - `rt_tick_from_millisecond()`:将 ms 转换为系统 tick > - 支持软定时器(由系统线程调度)和硬定时器(中断上下文) --- ### ✅ 6. 设备驱动模型(Device Driver Model) RT-Thread 提供统一设备接口,如串口、I2C、SPI、GPIO 等。 #### 示例:打开串口设备并发送数据 ```c #include <rtdevice.h> #include <rtthread.h> #define SAMPLE_UART_NAME "uart2" /* 串口号 */ struct rt_serial_device *serial; rt_device_t uart_device = RT_NULL; void uart_send_sample(void) { char msg[] = "Hello RT-Thread!\r\n"; uart_device = rt_device_find(SAMPLE_UART_NAME); if (uart_device != RT_NULL && rt_device_open(uart_device, RT_DEVICE_OFLAG_RDWR) == RT_EOK) { rt_device_write(uart_device, 0, msg, sizeof(msg) - 1); } } ``` 常用设备操作函数: | 函数 | 功能 | |------|------| | `rt_device_find(name)` | 查找设备 | | `rt_device_open(dev, flag)` | 打开设备 | | `rt_device_close(dev)` | 关闭设备 | | `rt_device_read()` | 读取数据 | | `rt_device_write()` | 写入数据 | | `rt_device_set_rx_indicate()` | 设置接收回调 | --- ### ✅ 7. FinSH 控制台命令导出 你可以将自定义函数注册为 FinSH 命令: ```c #include <finsh.h> void hello_cmd(void) { rt_kprintf("Welcome to RT-Thread CLI!\n"); } FINSH_FUNCTION_EXPORT(hello_cmd, Print welcome message); // 使用方法:在串口输入 `hello_cmd` 回车即可执行 ``` --- ### 总结:RT-Thread 主要标准接口分类 | 类别 | 主要函数前缀 | 说明 | |------|---------------|------| | 线程 | `rt_thread_` | 多任务调度 | | 信号量 | `rt_sem_` | 同步与资源计数 | | 互斥锁 | `rt_mutex_` | 资源独占访问 | | 消息队列 | `rt_mq_` | 数据通信 | | 事件集 | `rt_event_` | 多事件同步 | | 定时器 | `rt_timer_` | 时间触发 | | 设备模型 | `rt_device_` | 驱动抽象 | | 内存管理 | `rt_malloc`, `rt_free` | 动态内存分配 | | 中断管理 | `rt_interrupt_disable()` | 关中断 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值