0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

框架解耦神器 -- REventBus

Rice嵌入式开发技术分享 来源:Rice 嵌入式开发技术分享 作者:Rice 嵌入式开发技 2023-06-02 08:39 次阅读

REventBus背景

在实际的项目开发中,经常会遇到业务与业务,组件与组件,业务与组件之间的通信,举个例子:当有烟雾传感器检测到烟雾超标时,需要打开排气扇排气,同时显示烟雾浓度显示到显示器中,供管理人员检视。处理这样的逻辑有几种策略。如下:

  1. 排气扇任务和显示器任务,不断的查询烟雾浓度,各自处理检测烟雾浓度是否超标。
  2. 烟雾模块提供注册监听接口,排气扇任务和显示器任务分别注册监听,当浓度超标时,告知监听任务。

以上两种策略都存在很大的问题,问题分析:

  1. 第一种策略,每一个任务都需要不断检查判断,这会导致资源的浪费,而且代码也会有很多重复的。
  2. 第二种策略,虽然解决了第一种策略的的问题,但是如果场景中存在不止一个传感器时,那么所需要注册的监听接口将随之增加。而且监听接口是跟具体的业务绑定的。

综上所述:为了能够解决上面的问题,REventBus组件应运而生。

REventBus工作流程图解

Publisher使用publish发出ige一个事件,Subscriber在其回调函数中接收事件。dcbc327a-00dd-11ee-9c1d-dac502259ad0.png

REventBus依赖组件

为了提供更好的组件化,风火轮科技 和《Rice嵌入式开发技术分享》公众号联合推出R组件集,REventbus组件就是R组件集的其中一员,组件与组件之后存在依赖关系.REventBus组件同样依赖一些组件,如下:

  1. RPlatform组件:平台适配层,为了能让R组件能够在不同RTOSLinux中运行,针对不同平台做的适配层。链接:https://gitee.com/RiceChen0/rplatform。
  2. 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初始化接口
  1. 使用RThread_pool组件创建一个线程池
  2. 创建互斥量,解决共享资源问题。
  3. 初始化broker链表,用于事件代理。
pf_err_treb_init(void);
  • REventBus去初始化接口
  1. 线程池注销,互斥量伤处,
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演示

  1. 订阅事件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();
}
  • 效果:dcd2d70a-00dd-11ee-9c1d-dac502259ad0.png
  1. 发布同步事件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);
}
}
  • 效果:dcf9b7c6-00dd-11ee-9c1d-dac502259ad0.png
  1. 发布异步事件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);
}
}
  • 效果:dd263af8-00dd-11ee-9c1d-dac502259ad0.png

REventBus的优缺点

  • 优点:

  1. 简化组件与组件,业务与业务,组件与业务之间的通信方式。
  2. 对通信双方做到完全解耦。
  3. 使用RThread pool灵活切换工作线程,一定程度提供了事件处理效率
  4. 支持同步事件发布,和异步事件发布。
  5. 资源占用极小。
  • 缺点:

  1. 当业务多的时候,需要定义很多事件类型。
  2. 订阅事件的时候,需要遍历事件列表是否已经存在事件;发布的时候,也需要遍历事件列表是否已经存在事件,性能不高。
dd4932e2-00dd-11ee-9c1d-dac502259ad0.png


审核编辑黄宇


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8454

    浏览量

    150741
  • 框架
    +关注

    关注

    0

    文章

    398

    浏览量

    17408
  • 解耦
    +关注

    关注

    0

    文章

    40

    浏览量

    11883
收藏 人收藏

    评论

    相关推荐

    详解Board和SoC的设计思路

    本文简单介绍OpenHarmony轻量系统移植,Board和SoC的设计思路。适合自己动手移植OpenHarmony轻量系统的朋友们。
    的头像 发表于 03-03 09:50 5339次阅读
    详解Board和SoC<b class='flag-5'>解</b><b class='flag-5'>耦</b>的设计思路

    永磁同步电机偏差和电流前馈控制比较

    偏差控制:电机参数估计值采用估计值加上电流反馈补偿d轴电流:电机参数准确值采用准确值加上电流反馈补偿d轴电流:电机参数采用估计值加上偏差控制:电机参数采用准确值加上偏差
    发表于 06-28 06:08

    常用的设计方法

    在采用传统无动态控制时,uqu_quq​和udu_dud​的指令值存在耦合项。上一个学习笔记中设计的设计方法是将其忽略,因此在最后设计的效果并不太好。目前,常用的设计方法,有前
    发表于 08-27 07:29

    永磁同步电机偏差与电流前馈控制对比分析,哪个影响大?

    永磁同步电机偏差与电流前馈控制对比分析,哪个影响大?
    发表于 10-12 10:17

    电压前馈是如何实现的

    电压前馈是什么?电压前馈是如何实现的?
    发表于 10-15 06:55

    多变量控制实验

    多变量控制4.0 实验设备PC计算机1台(要求P4-1.8G以上)、MATLAB6.X软件1套。4.1 实验目的①学习多变量控制方法。②通过用MATLAB编程、上机调试,掌握多
    发表于 05-15 00:51 0次下载

    热连轧机活套系统的控制及仿真

    针对传统热连轧带钢活套张力与高度控制系统,本文给出了基于对角矩阵和解不变性原理的控制方法。通过耦合系统的动态结构图,求取活套耦合系
    发表于 08-04 15:27 11次下载

    基于补偿器的控制方法的研究

    本文通过对冷热水混合系统的温度和液位的双变量耦合问题进行分析,提出了一种满足要求和控制目标需要的基于补偿器的Smith预估控制方法。试验结果表明,
    发表于 02-11 14:38 10次下载

    先进PID多变量控制

    先进PID多变量控制 通过PID控制,可实现对多变量系统的控制
    发表于 05-04 16:01 40次下载

    多变量自适应控制及应用

    多变量自适应控制及应用,有需要的朋友下来看看。
    发表于 04-12 10:21 0次下载

    初值设定对快速法潮流计算的影响研究

    初值设定对快速法潮流计算的影响研究
    发表于 01-23 14:13 0次下载

    基于H∞混合灵敏度控制器实现BTT导弹自动驾驶仪的设计

    导弹在大攻角飞行过程中,通道间存在严重的气动耦合。工程设计上,通常把较小的耦合项作为随机干扰来处理,但当耦合影响较大时,容易使控制系统丧失稳定性,因此必须考虑通道间的耦合效应,并对其。近年来
    发表于 05-17 10:35 1098次阅读

    电容如何放置

    警告: 请注意电容的位置,尤其是IC芯片的电源与地引脚是斜对角的。 潜在问题: 不合理的位置会导致不充分的。 预防措施: -对于像直插这样的IC,其电源端子与地是端子成对角放置
    的头像 发表于 09-30 09:18 4054次阅读
    电容<b class='flag-5'>解</b><b class='flag-5'>耦</b>如何放置

    永磁同步电机控制之反馈及复矢量

    永磁同步电机反馈及复矢量(无刷直流电机等交流电机同样适用) 一、永磁同步电机数学模型 1.永磁同步电机dq坐标系数学模型 2.永磁同步电机复矢量数学模型 二、
    发表于 03-09 10:09 0次下载
    永磁同步电机控制之反馈<b class='flag-5'>解</b><b class='flag-5'>耦</b>及复矢量<b class='flag-5'>解</b><b class='flag-5'>耦</b>

    框架神器REventBus

    在实际的项目开发中,经常会遇到业务与业务,组件与组件,业务与组件之间的通信,举个例子:当有烟雾传感器检测到烟雾超标时,需要打开排气扇排气,同时显示烟雾浓度显示到显示器中,供管理人员检视。
    的头像 发表于 06-06 16:44 563次阅读
    <b class='flag-5'>框架</b><b class='flag-5'>解</b><b class='flag-5'>耦</b><b class='flag-5'>神器</b>—<b class='flag-5'>REventBus</b>