打印
[单片机芯片]

事件驱动框架(开源代码)

[复制链接]
572|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
MacRsh|  楼主 | 2023-7-5 21:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 MacRsh 于 2023-7-5 21:14 编辑

事件驱动框架是一种异步事件处理机制,它通过事件分发和回调的方式,可以有效地提高系统的异步处理能力、解耦性和可扩展性。
事件驱动框架包含两个主要组件:事件服务器和事件客户端。
  • 事件服务器用于接收和分发事件,它内部维护一个事件队列用于存储待处理事件和一个事件列表用于存储注册的事件客户端。
  • 事件客户端用于处理特定类型的事件,它需要注册到事件服务器并提供一个回调函数。
当事件发生时,事件服务器会将事件插入到其事件队列中进行缓存。事件服务器会周期性地从事件队列中取出事件进行分发,找到对应的事件客户端,然后调用其注册的回调函数进行事件处理。

事件驱动框架代码模块,可无依赖,快速的部署到工程应用中。
事件驱动框架原型


<div><span class="code-block-extension-codeLine" data-line-num="1">/* 事件服务器 */</span>
<span class="code-block-extension-codeLine" data-line-num="2"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">event_server</span></span></span></div><div>
<span class="code-block-extension-codeLine" data-line-num="3">{</span> </div><div><span class="code-block-extension-codeLine" data-line-num="4"><span class="hljs-class"><span class="hljs-keyword">    struct</span> <span class="hljs-title">event_fifo</span> <span class="hljs-title">queue</span>;</span>                                        <span class="hljs-comment">/* 事件队列 */</span></span> </div><div><span class="code-block-extension-codeLine" data-line-num="5"><span class="hljs-type">    event_avl_t</span> <span class="hljs-built_in">list</span>;                                               <span class="hljs-comment">/* 事件链表 */</span></span> </div><div><span class="code-block-extension-codeLine" data-line-num="6">};</span></div>

  • queue:事件队列(用于存储要唤醒的客户端ID)。
  • list:服务器链表(用于存储客户端)。

/* 事件客户端 */
struct event_client
{
    struct event_avl list;                                          /* 事件链表 */
   
    mr_err_t (*cb)(event_server_t server, void *args);              /* 事件回调函数 */
    void *args;                                                     /* 事件回调函数参数 */
};

  • list:客户端链表(用于将客户端添加到服务器的客户端列表中)。
  • cb:回调函数。
  • args:回调函数参数。


初始化服务器
int event_server_init(mr_event_server_t server,mr_size_t queue_length);


[td]
参数
描述
server
服务器句柄
queue_length
服务器队列长度(同时处理事件的个数)
返回

EVENT_ERR_OK
添加成功
错误码
添加失败



重置服务器
int event_server_uninit(event_server_t server);



[td]
参数
描述
server
服务器句柄
返回

EVENT_ERR_OK
移除成功
错误码
移除失败



通知服务器,事件发生
int event_server_notify(event_server_t server, uint8_t id);



[td]
参数
描述
server
服务器句柄
id
发生事件的客户端id
返回

EVENT_ERR_OK
通知成功
错误码
通知失败




服务器分发事件,唤醒客户端

void event_server_handle(event_server_t server);


[td]
参数
描述
server
服务器句柄



查找客户端
event_client_t event_client_find(uint8_t id, event_server_t server);


[td]
参数
描述
id
客户端id
server
服务器句柄
返回

客户端句柄
查找成功
NULL
查找失败



创建新客户端
int event_client_create(uint8_t id,
                        int (*cb)(event_server_t server, void *args),
                        void *args,
                        event_server_t server);


[td]
参数
描述
id
客户端id
cb
回调函数
args
回调函数参数
server
服务器句柄
返回

EVENT_ERR_OK
创建成功
错误码
创建失败



删除客户端
int client_delete(uint8_t id, event_server_t server);


[td]
参数
描述
id
客户端id
server
服务器句柄
返回

EVENT_ERR_OK
删除成功
错误码
删除失败




使用示例:

/* 定义事件 */
#define EVENT1                          1
#define EVENT2                          2
#define EVENT3                          3

/* 定义事件服务器 */
struct event_server event_server;

int event1_cb(event_server_t server, void *args)
{
    printf("event1_cb\r\n");
   
    /* 通知事件服务器事件2发生 */
    event_server_notify(server, EVENT2);
   
    return 0;
}

int event2_cb(event_server_t server, void *args)
{
    printf("event2_cb\r\n");
   
    /* 通知事件服务器事件3发生 */
    event_server_notify(server, EVENT3);
   
    return 0;
}

int event3_cb(event_server_t server, void *args)
{
    printf("event3_cb\r\n");
   
    return 0;
}

int main(void)
{
    /* 添加事件服务器到内核容器 */
    event_server_init(&event_server, 4);
   
    /* 创建事件客户端到事件服务器 */
    event_client_create(EVENT1, event1_cb, NULL, &event_server);
    event_client_create(EVENT2, event2_cb, NULL, &event_server);
    event_client_create(EVENT3, event3_cb, NULL, &event_server);
   
    /* 通知事件服务器事件1发生 */
    event_server_notify(&event_server, EVENT1);
   
    while (1)
    {
        event_server_handle(&event_server);


现象:

event1_cb
event2_cb
event3_cb

下载代码(https://gitee.com/MacRsh/mr-library/tree/master/(路径:mr-library/ package / event)



许可协议
遵循 Apache License 2.0 开源许可协议,可免费应用于商业产品,无需公开私有代码。





使用特权

评论回复
沙发
tpgf| | 2023-8-1 13:15 | 只看该作者
一个事件驱动框架(EDA)定义了一个设计和实现一个应用系统的方法学,在这个系统里事件可传输于松散耦合的组件和服务之间

使用特权

评论回复
板凳
nawu| | 2023-8-1 16:54 | 只看该作者
一个事件驱动系统典型地由事件消费者和事件产生者组成

使用特权

评论回复
地板
aoyi| | 2023-8-1 17:36 | 只看该作者
事件消费者向事件管理器订阅事件,事件产生者向事件管理器发布事

使用特权

评论回复
5
Tompannj| | 2023-8-1 23:05 | 只看该作者
牛X

使用特权

评论回复
6
caigang13| | 2023-8-2 07:32 | 只看该作者
楼主自己写的吗?

使用特权

评论回复
7
caigang13| | 2023-8-2 07:32 | 只看该作者
楼主自己写的吗?

使用特权

评论回复
8
zljiu| | 2023-8-2 08:26 | 只看该作者
当事件管理器从事件产生者那接收到一个事件时,事件管理把这个事件转送给相应的事件消费者。如果这个事件消费者是不可用的,事件管理者将保留这个事件,一段间隔之后再次转送该事件消费者。这种事件传送方法在基于消息的系统里就是:储存(store)和转送(forward)。

使用特权

评论回复
9
gwsan| | 2023-8-2 09:45 | 只看该作者
由于在一个EDA系统中各个组件都只专注于处理输入的消息与发布输出的消息,因而EDA系统能够更有加效地对管道化(pipelined)的、由多软件模块链接而成的并发事件流(concurrent processing of events)进行处理。

使用特权

评论回复
10
tfqi| | 2023-8-3 10:50 | 只看该作者
EDA提高了对不断变化的业务需求的响应,最大限度地减少了对现有业务应用的影响,也常消除了对新打包应用的需要

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

16

帖子

1

粉丝