REventBus背景
在实际的项目开发中,经常会遇到业务与业务,组件与组件,业务与组件之间的通信,举个例子:当有烟雾传感器检测到烟雾超标时,需要打开排气扇排气,同时显示烟雾浓度显示到显示器中,供管理人员检视。处理这样的逻辑有几种策略。如下:
- 排气扇任务和显示器任务,不断的查询烟雾浓度,各自处理检测烟雾浓度是否超标。
- 烟雾模块提供注册监听接口,排气扇任务和显示器任务分别注册监听,当浓度超标时,告知监听任务。
以上两种策略都存在很大的问题,问题分析:
- 第一种策略,每一个任务都需要不断检查判断,这会导致资源的浪费,而且代码也会有很多重复的。
- 第二种策略,虽然解决了第一种策略的的问题,但是如果场景中存在不止一个传感器时,那么所需要注册的监听接口将随之增加。而且监听接口是跟具体的业务绑定的。
综上所述:为了能够解决上面的问题,REventBus组件应运而生。
REventBus工作流程图解
Publisher使用publish发出ige一个事件,Subscriber在其回调函数中接收事件。
REventBus依赖组件
为了提供更好的组件化,风火轮科技 和《Rice嵌入式开发技术分享》公众号联合推出R组件集,REventbus组件就是R组件集的其中一员,组件与组件之后存在依赖关系.REventBus组件同样依赖一些组件,如下:
- RPlatform组件:平台适配层,为了能让R组件能够在不同RTOS或Linux中运行,针对不同平台做的适配层。链接:https://gitee.com/RiceChen0/rplatform。
- RThread_pool组件:一个跨平台,易移植,接口简单的线程池组件。链接:https://gitee.com/RiceChen0/rthread_pool。
REventBus的使用
- REventBus整体包含5部分:Subscribe,Publish,Event,EventCb,Broker。
- Subscribe --订阅者订阅自己需要监听的事件接口。
- Publish --发布者发布事件,它支持同步发送和异步发送。
- Event --订阅者监听的事件,只有存在订阅事件,才会有与之对应的发布事件。
- EventCb --事件产生的回调接口,订阅者注册,发布者发布对应事件之后产生回调。
- Broker --事件代理,管理事件注册,注销,监听。
REventBus接口说明
接口 | 说明 |
---|---|
reb_init | REventBus初始化接口 |
reb_deinit | REventBus去初始化接口 |
reb_subscribe | REventBus订阅事件接口 |
reb_unsbscribe | REventBus取消订阅事件接口 |
reb_publish | REventBus同步发布事件接口 |
reb_async_publish | REventBus异步发布事件接口 |
- REventBus初始化接口
- 使用RThread_pool组件创建一个线程池
- 创建互斥量,解决共享资源问题。
- 初始化broker链表,用于事件代理。
pf_err_treb_init(void);
- REventBus去初始化接口
- 线程池注销,互斥量伤处,
pf_err_treb_deinit(void);
- REventBus订阅事件接口: pf_err_t reb_subscribe(const char *event, reb_handler_cb handler)
「参数」 | 「描述」 |
---|---|
event | 订阅的事件,其是一个字符串类型 |
handler | 事件处理函数,由订阅者提供,事件产生时回调此函数 |
「返回」 | —— |
PF_EOK | 订阅事件成功 |
OTher | 订阅事件失败 |
- REventBus订阅事件接口: pf_err_t reb_unsbscribe(const char *event, reb_handler_cb handler)
「参数」 | 「描述」 |
---|---|
event | 订阅的事件,其是一个字符串类型 |
handler | 事件处理函数,订阅事件时所订阅的回调函数 |
「返回」 | —— |
PF_EOK | 取消订阅事件成功 |
OTher | 取消订阅事件失败 |
- REventBus同步发布事件接口:pf_err_t reb_publish(const char *event, void *payload, uint16_t lenght)
「参数」 | 「描述」 |
---|---|
event | 订阅者订阅的事件类型 |
payload | 发布事件的消息类型 |
lenght | 发布事件的消息长度 |
「返回」 | —— |
PF_EOK | 发布事件成功 |
OTher | 发布事件失败 |
- REventBus异步发布事件接口:pf_err_t reb_async_publish(const char *event, reb_priority priority, void *payload, uint16_t lenght)
「参数」 | 「描述」 |
---|---|
event | 订阅者订阅的事件类型 |
priority | 发布事件的优先级,REB_PRIORITY_HIGH和REB_PRIORITY_ORDINARY(目前未实现) |
payload | 发布事件的消息类型 |
lenght | 发布事件的消息长度 |
「返回」 | —— |
PF_EOK | 发布事件成功 |
OTher | 发布事件失败 |
REventBus演示
- 订阅事件demo:
- 注意:同一个模块定义多次定义同一个事件,只有第一个事件订阅有效
#include
#include
#include
#include"revent_bus.h"
voidreb_handler(constchar*event,void*payload,uint16_tlenght)
{
rt_kprintf("Recv:event:%s,payload:%.*srn",event,lenght,payload);
}
intmain(void)
{
reb_init();
reb_subscribe("event1",reb_handler);
reb_subscribe("event1",reb_handler);
reb_subscribe("event2",reb_handler);
reb_info_dump();
}
- 效果:
- 发布同步事件demo:
- 注意:发布同步事件,它是按照顺序发布的,只有第一个事件处理完,才会处理第二个事件。
#include
#include
#include
#include"revent_bus.h"
voidreb_handler(constchar*event,void*payload,uint16_tlenght)
{
rt_kprintf("Recv:event:%s,payload:%.*srn",event,lenght,payload);
}
intmain(void)
{
rt_kprintf("----------------------rn");
rt_kprintf("-Webcometoyouyeetoo-rn");
rt_kprintf("----------------------rn");
reb_init();
reb_subscribe("event1",reb_handler);
reb_subscribe("event1",reb_handler);
reb_subscribe("event2",reb_handler);
reb_info_dump();
while(1)
{
reb_publish("event1","youyeetoo:eventbus",rt_strlen("youyeetoo:eventbus"));
reb_publish("event2","Publishsyncmsg",rt_strlen("Publishsyncmsg"));
rt_thread_delay(1000);
}
}
- 效果:
- 发布异步事件demo:
- 注意:发布异步事件,发布的事件不一定立马执行,他会等待线程池的任务空闲时,才会执行。也就是执行时间不确定。
#include
#include
#include
#include"revent_bus.h"
voidreb_handler(constchar*event,void*payload,uint16_tlenght)
{
rt_kprintf("Recv:event:%s,payload:%.*srn",event,lenght,payload);
}
intmain(void)
{
rt_kprintf("----------------------rn");
rt_kprintf("-Webcometoyouyeetoo-rn");
rt_kprintf("----------------------rn");
reb_init();
reb_subscribe("event1",reb_handler);
reb_subscribe("event1",reb_handler);
reb_subscribe("event2",reb_handler);
reb_info_dump();
while(1)
{
reb_publish("event1","youyeetoo:eventbus",rt_strlen("youyeetoo:eventbus"));
reb_publish("event2","Publishsyncmsg",rt_strlen("Publishsyncmsg"));
rt_thread_delay(100);
reb_async_publish("event1",REB_PRIORITY_ORDINARY,"GoodGood",rt_strlen("GoodGood"));
reb_async_publish("event2",REB_PRIORITY_ORDINARY,"Publishasyncmsg",rt_strlen("Publishasyncmsg"));
rt_thread_delay(100);
}
}
- 效果:
REventBus的优缺点
-
优点:
- 简化组件与组件,业务与业务,组件与业务之间的通信方式。
- 对通信双方做到完全解耦。
- 使用RThread pool灵活切换工作线程,一定程度提供了事件处理效率
- 支持同步事件发布,和异步事件发布。
- 资源占用极小。
-
缺点:
- 当业务多的时候,需要定义很多事件类型。
- 订阅事件的时候,需要遍历事件列表是否已经存在事件;发布的时候,也需要遍历事件列表是否已经存在事件,性能不高。
审核编辑黄宇
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
接口
+关注
关注
33文章
7648浏览量
148533 -
框架
+关注
关注
0文章
297浏览量
17047 -
解耦
+关注
关注
0文章
40浏览量
11835
发布评论请先 登录
相关推荐
0058《多变量自适应解耦控制及应用》.pdf
1000本电子专业书籍免费大放送https://bbs.elecfans.com/forum.php?mod=viewthread&tid=287358&fromuid=286650058《多变量自适应解耦控制及应用》.pdf(4M)希望大家多顶顶,提升提升人气。
发表于 01-15 13:30
求助解答关于异步电机矢量控制中磁链环和电压前馈解耦问题??
在异步电机矢量控制中,磁链的给定值怎么计算?我怎么知道我这个磁链的给定值应该设置成多少??在电流控制器后一个电压的前馈解耦环节?不说很清楚解耦环节的公式怎么来的?不知道有哪位朋友能够提
发表于 11-23 20:54
通过电能缓冲进行负载解耦的智能电表电源管理方案
的解决方案,具有更低的电流和发送给无线电的高电流脉冲。这些脉冲从电池通过电能缓冲进行解耦。主要特色 降压 (MCU) 和升压 (RF-PA) 轨通过电能缓冲进行负载解耦超低功耗 Iq通
发表于 11-13 16:55
永磁同步电机偏差解耦和电流前馈解耦控制比较
偏差解耦控制:电机参数估计值采用估计值加上电流反馈补偿d轴电流:电机参数准确值采用准确值加上电流反馈补偿d轴电流:电机参数采用估计值加上偏差解耦控制:电机参数采用准确值加上偏差
发表于 06-28 06:08
单相dq解耦控制 精选资料下载
1.单相dq解耦 本周重点剖析单相dq解耦的方式,发现很多论文上关于dq轴的定义都不一样,以及dq变换矩阵的定义都不同,让人感到眼花缭乱,不知道到底哪一个是正确的,经过多篇文献的分析
发表于 07-09 06:41
永磁同步电机矢量控制是如何将三相电流解耦的
永磁同步电机控制系统是多变量、强耦合的时变非线性系统,要进行高性能控制,获得良好的动态稳态特性,常用的方法是矢量控制。永磁同步电机矢量控制是通过坐标变换的方式将三相电流解耦,以控制其中一项来达到控制
发表于 08-27 06:04
一种基于滑模观测器的电流偏差解耦控制方法
每日文献|带你坚持阅读掌握行业最前沿技术邀请|关注公众号,在公众号后台回复交流群,加入群聊每天获取最新文献资讯「 iFTrue 未来已来 」概述为解决传统电压前馈解耦控制对电机参数敏感、抗扰性差
发表于 08-27 06:41
常用的解耦设计方法
在采用传统无动态解耦控制时,uqu_quq和udu_dud的指令值存在耦合项。上一个学习笔记中设计的设计方法是将其忽略,因此在最后设计的效果并不太好。目前,常用的解耦设计方法,有前
发表于 08-27 07:29
如何使用异步生成器解耦业务逻辑
异步解耦Async generators are new in JavaScript. They are a remarkable extension. They provide a simple
发表于 09-06 09:11
系统和用户数据解耦的方法
前言:本章内容仅做了解,实际开发中,从安全和资源要求为出发点,根文件系统必须是只读的;下个章节会介绍一种系统和用户数据解耦的方法。1 简述我们在buildroot后会得到两个根文件系统,目录如下:一
发表于 12-27 08:29
框架解耦神器—REventBus
在实际的项目开发中,经常会遇到业务与业务,组件与组件,业务与组件之间的通信,举个例子:当有烟雾传感器检测到烟雾超标时,需要打开排气扇排气,同时显示烟雾浓度显示到显示器中,供管理人员检视。
评论