Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
3.1.5
rt_event_事件集
10
事件集:为什么发送事件的时候也需要清空标志位,而不是全部都在接受处理后清空
发布于 2021-11-22 10:01:09 浏览:1424
订阅该版
**RT-thread 标准版 3.1.5** 目前有个想法,通过使用事件集来表示一组命令,判断逻辑如下所示: ```c if (rt_event_recv(event, 0xFFFFFFFF, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &e) == RT_EOK) { /* 对接受到事件轮询处理 */ while (e) { /* 获取第一个为1 bit的位置 */ rt_uint8_t fisrtBit = __rt_ffs(e) - 1; rt_kprintf("%s receive %d\n", event->parent.parent.name, fisrtBit); /* 清除对应标志位 */ e &= ~(1ul << fisrtBit); } } ``` 但是此时有个问题,如果在短时间内多次发送同一命令(接受处理线程优先级较低,全部发送完后才会进行调度),例如: ``` rt_event_send(event, 1 << 0); rt_event_send(event, 1 << 0); rt_event_send(event, 1 << 0); rt_event_send(event, 1 << 0); ``` 则此时接受函数这边会处理两次,打印结果如下所示 ``` cmd0 receive 0 cmd0 receive 0 ``` 通过分析源代码,原因是:首次发送的时候进行了标志位的清空,但是由于接受处理线程的优先级较低,此时不会产生调度,当再次调用rt_event_send,此时不满足条件,不会清空标志位。当全部发送完成后,此时产生系统调度,执行rt_event_recv中rt_schedule()后续代码,但是由于对应标志位还是置1,因此还会再接受一次,最终输出两次打印结果。以下为rt_event_send与rt_event_recv部分代码以及一些自己注释 ```c /* rt_event_send 部分处理代码 */ /* condition is satisfied, resume thread */ if (!rt_list_isempty(&event->parent.suspend_thread)) { /* search thread list to resume thread */ n = event->parent.suspend_thread.next; while (n != &(event->parent.suspend_thread)) { /* get thread */ thread = rt_list_entry(n, struct rt_thread, tlist); status = -RT_ERROR; if (thread->event_info & RT_EVENT_FLAG_AND) { if ((thread->event_set & event->set) == thread->event_set) { /* received an AND event */ status = RT_EOK; } } else if (thread->event_info & RT_EVENT_FLAG_OR) { if (thread->event_set & event->set) { /* save the received event set */ thread->event_set = thread->event_set & event->set; /* received an OR event */ status = RT_EOK; } } else { /* enable interrupt */ rt_hw_interrupt_enable(level); return -RT_EINVAL; } /* move node to the next */ n = n->next; /* condition is satisfied, resume thread */ if (status == RT_EOK) { /* 为什么在发送的时候清空? */ /* clear event */ if (thread->event_info & RT_EVENT_FLAG_CLEAR) event->set &= ~thread->event_set; /* resume thread, and thread list breaks out */ rt_thread_resume(thread); /* need do a scheduling */ need_schedule = RT_TRUE; } } } ``` ``` /* rt_event_recv 部分处理代码 */ /* do a schedule */ rt_schedule(); if (thread->error != RT_EOK) { /* return error */ return thread->error; } /* 为什么不在这里再清空标志位 */ /*if (xxx) clear flag; */ /* received an event, disable interrupt to protect */ level = rt_hw_interrupt_disable(); /* set received event */ if (recved) *recved = thread->event_set; ``` 疑问:为什么要在发送的时候清空标志位,而不是统一在接受的时候再清空,麻烦各位大佬解答一下,谢谢。 PS: 若有其它意见或问题,也请提出,一起探讨,- 。-。
查看更多
3
个回答
默认排序
按发布时间排序
出出啊
2021-11-22
恃人不如自恃,人之为己者不如己之自为也
这个看你了,你能保证发送前的状态是可知的,什么时候清理都可以。 你说的这个发送的时候,清空,需要初始化了 RT_EVENT_FLAG_CLEAR 才有效,不设置这个 flag 就不会清空。
张世争
2021-11-22
学以致用
根据应用的,如果重复置位两次或多次,并且想全部接收到状态改变,建议使用消息队列状态机的方式处理命令。
yks
2021-11-23
这家伙很懒,什么也没写!
学习了? 按照我以前的理解,这么连续发多次事件,最终只会处理一次,今天刷新了认知?
撰写答案
登录
注册新账号
关注者
0
被浏览
1.4k
关于作者
樂飓颩俠
抱大腿
提问
10
回答
3
被采纳
0
关注TA
发私信
相关问题
1
rt_thread事件某位如何置0,如何简单获取某位状态
2
有单独清除事件标志的函数么?
3
rt_event事件问题
4
事件集的选择清除重置事件标志位
5
Nano 内核FinSH 的 list_event 查询问题
6
Nano 初始化两次 event,使用list_event 导致的问题
7
关于事件集和邮箱那一块
8
rt-thread事件集多线程接收的一个疑问?
9
事件集在中断服务函数与线程之间的同步的疑问
10
生产者消费者中是否可以使用一个事件集来代替多个二值信号量?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
简单两步配置RTT源码阅读环境 vsc+clangd
2
恩智浦[FRDM-MCXN947]初探 之 ADC与DAC
3
LVGL使用字库IC芯片显示中文
4
基于STM32H750和Rt-Thread的CANFD通信实现的记录(一)
5
freemodbus主机在freertos的适配,参考rtthread例程
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部