MCU订阅-发布模式

news/2024/12/22 2:35:17/

在**uMCN(Micro Communication Node)**模块中,多个数据结构协同工作,实现发布-订阅机制。下面是uMCN中各个核心数据结构的详细功能解释。

1. McnHub 结构体:消息中心

功能McnHub 是 uMCN 中的核心结构体,代表一个具体的消息主题(Topic)。它负责管理数据的发布和订阅,以及维护订阅者节点的链表。

struct mcn_hub {const char* obj_name;         // 主题名称,用于唯一标识const uint32_t obj_size;      // 主题数据的大小void* pdata;                  // 指向存储发布的数据的指针McnNode_t link_head;          // 订阅者链表的头节点McnNode_t link_tail;          // 订阅者链表的尾节点uint32_t link_num;            // 当前订阅者数量uint8_t published;            // 标志该主题是否已发布数据uint8_t suspend;              // 标志该主题是否暂停发布rt_event_t event;             // 用于事件通知的RTOS事件int (*echo)(void* parameter); // 打印主题内容的回调函数float freq;                   // 发布频率估算值uint16_t freq_est_window[MCN_FREQ_EST_WINDOW_LEN]; // 发布频率估算窗口uint16_t window_index;        // 当前频率窗口索引
};
详细解释:
  • obj_name:表示主题的名字,通过它标识不同的主题。订阅者通过该名称来订阅主题。
  • obj_size:保存主题数据的大小,定义了该主题发布的数据类型和所需的存储空间。例如,如果发布的数据是 float 类型,obj_size 将是 sizeof(float)
  • pdata:这是一个指向实际存储发布数据的指针。通过这个指针,发布的数据会存储在该内存区域中,并且当新的数据发布时,旧数据会被覆盖。
  • link_headlink_tail:这是一个链表结构,存储了所有订阅该主题的订阅者节点(McnNode)。通过这两个指针,uMCN 可以高效地管理订阅者。
  • link_num:表示当前订阅该主题的订阅者数量。
  • published:标志主题是否已经发布过数据。如果为 1,表示主题已经有数据发布过。
  • suspend:标志主题是否被暂停发布。设置为 1 时,主题将不会接收新的发布数据。
  • event:在实时操作系统(RTOS)中用于订阅者等待事件通知,表示主题的发布事件。
  • freq:保存发布频率的估算值。
  • freq_est_windowwindow_index:用于估算发布频率的滑动窗口,记录最近几次的发布时间间隔。

2. McnNode 结构体:订阅者节点

功能McnNode 代表一个订阅者,它存储与某个主题的订阅信息。每个订阅者节点都会挂在 McnHub 的订阅者链表上。

struct mcn_node {McnHub_t hub;             // 指向订阅的消息中心(主题)volatile uint8_t renewal; // 标志订阅者是否收到了新的数据void (*pub_cb)(void* parameter); // 发布数据时的回调函数McnNode_t next;           // 链表中的下一个订阅者节点
};
详细解释:
  • hub:指向当前订阅的主题(McnHub),即该订阅者关注的消息中心。
  • renewal:这是一个标志位,表示该订阅者是否接收到了新的数据。当 mcn_publish() 函数发布数据时,所有订阅者的 renewal 标志都会被设置为 1
  • pub_cb:发布数据时调用的回调函数。当主题发布新的数据时,系统会遍历订阅者链表,调用每个订阅者的回调函数以通知它们数据更新。
  • next:指向下一个订阅者节点,实现订阅者链表。

3. McnList 结构体:消息中心链表

功能McnList 用于维护系统中所有的 McnHub,即消息中心的链表。每个消息中心(主题)都会作为一个节点保存在该链表中。

struct mcn_list {McnHub_t hub;    // 指向当前链表节点的消息中心(主题)McnList_t next;  // 指向下一个消息中心
};
详细解释:
  • hub:指向链表中的一个 McnHub,即一个具体的主题。
  • next:指向下一个链表节点,实现所有主题的管理。通过这个链表,uMCN可以访问系统中的所有已定义的消息中心。

4. 辅助宏与常量

  • MCN_DECLAREMCN_DEFINE

    • MCN_DECLARE:用于在代码的其他部分声明一个消息主题。
    • MCN_DEFINE:用于定义一个消息主题,并为其分配内存。

    例如:

MCN_DEFINE(temp_sensor, sizeof(float));  // 定义一个浮点类型的主题

5. mcn_publish() 函数:发布数据

功能:数据发布由 mcn_publish() 函数完成。它将数据复制到消息中心,并遍历订阅者链表,更新每个订阅者的更新标志并调用回调函数。

fmt_err_t mcn_publish(McnHub_t hub, const void* data) {...memcpy(hub->pdata, data, hub->obj_size);  // 将数据复制到已分配的内存...// 遍历所有订阅者并更新其 renewal 标志McnNode_t node = hub->link_head;while (node != NULL) {node->renewal = 1;  // 标志订阅者接收到新数据if (node->pub_cb != NULL) {node->pub_cb(hub->pdata);  // 调用订阅者的回调函数}node = node->next;}...
}

6. mcn_subscribe() 函数:订阅主题

订阅者通过 mcn_subscribe() 函数订阅消息(将订阅者节点挂在消息中心的订阅者链表中),并注册一个回调函数用于处理数据更新。

McnNode_t mcn_subscribe(McnHub_t hub, void (*pub_cb)(void* parameter)) {...node->pub_cb = pub_cb;  // 注册订阅者的回调函数...hub->link_num++;return node;
}

7. mcn_copy() 函数:数据复制

功能:订阅者可以通过 mcn_copy() 从消息中心复制最新的数据到订阅者的缓冲区中。这是确保订阅者能获取最新数据的关键步骤。

fmt_err_t mcn_copy(McnHub_t hub, McnNode_t node_t, void* buffer) {memcpy(buffer, hub->pdata, hub->obj_size);  // 将数据复制到订阅者的缓冲区return FMT_EOK;
}

8. 主题的声明与定义 

#define MCN_DECLARE(_name) extern McnHub __mcn_##_name
#define MCN_DEFINE(_name, _size) \McnHub __mcn_##_name = {     \.obj_name = #_name,      \.obj_size = _size,       \.pdata = NULL,           \.link_head = NULL,       \.link_tail = NULL,       \.link_num = 0,           \.published = 0,          \.suspend = 0,            \.freq = 0.0f             \}

总结

  • McnHub 是 uMCN 的核心结构,负责管理主题的发布和订阅。
  • McnNode 代表订阅者,管理订阅的主题和数据更新的回调函数。
  • McnList 用于维护所有消息中心的链表。
  • uMCN通过这些结构实现了一个高效的发布-订阅系统,保证了发布者和订阅者之间的松耦合和数据的一致性。



http://www.ppmy.cn/news/1535119.html

相关文章

【评测】湖北十堰大带宽300M高防云服务器

湖北十堰的高防服务器拥有高性能处理器、大容量DDR4 ECC内存、SSD硬盘及多种带宽配置,性价比高且配置灵活。它防御强劲,性能稳定可靠,扩展性佳,可满足各类企业需求,是优质服务器的绝佳选择。 清风云官网:ht…

Java API接口开发规范

文章目录 一、命名规范1.1 接口命名1.2 变量命名 二、接收参数规范2.1 请求体(Body)2.2 查询参数(Query Parameters) 三、参数检验四、接收方式规范五、异常类处理六、统一返回格式的定义七、API接口的幂等性(Idempote…

在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型

在深度学习模型的训练过程中,学习率作为一个关键的超参数,对模型的收敛速度和最终性能有着重大影响。传统方法通常采用统一的学习率,但随着研究的深入,我们发现为网络的不同层设置不同的学习率可能会带来显著的性能提升。本文将详…

震动传感器介绍及实战

目录 前言 震动传感器 1.震动传感器配图 2.震动传感器原理图 3.震动传感器使用 1-震动传感器的意义 2-震动传感器的应用场景 3- SW-18010P震动传感器使用方法 震动传感器控制灯 操作 增加延时 使用SPC-ISP生成演示函数 总结 前言 我们上节已经简单了解了LED的使用…

Github 2024-10-05Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-10-05统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10HTML项目1Move项目1Python项目1精选Rust资源清单 创建周期:3733 天开发语言:Rust协议类型:Creative Commons Zero v1.0 Universal…

第十四届蓝桥杯真题Java c组D.平均(持续更新)

博客主页:音符犹如代码系列专栏:蓝桥杯关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 【问题描述】 有一个长度为n的数组(n是10的倍数),每个数 …

区间覆盖(贪心)

给定 NN 个闭区间 [ai,bi][ai,bi] 以及一个线段区间 [s,t][s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。 输出最少区间数,如果无法完全覆盖则输出 −1−1。 输入格式 第一行包含两个整数 ss 和 tt,表示给定线段区间的两…

低功耗4G模组Air780E之串口通信篇

你对低功耗4G模组Air780E有多少了解? 今天我们来讲解低功耗4G模组Air780E的串口通信的基本用法,小伙伴们,学起来吧! 一、硬件准备 780E开发板一套,包括天线、USB数据线。 USB转TTL工具或线(例如ch340、…