- Local DDS,简化版DDS,实现MCU本地数据分发服务;
- 兼容linux、windows、mac、freertos等支持标准c++11容器库的系统;
- 实现类以ROS系统的开发模式,简化软件的设计开发流程,可以支撑不同规范的团队协作开发;
- 封装了c接口,方便不熟悉c++的单片机开发者使用;
- 已经在esp32和linux平台验证使用;
模块创建节点,订阅主题时向消息框架实现主题与节点的绑定。节点内部有一个主题管理表,用于主题与消息处理函数的绑定。
/**
* @brief 分布式消息框架拓扑
* @param platform消息平台,消息总线挂载在消息平台上
* @param bus消息总线,消息总线每个主题对应一条消息总线
* @param node角色节点,订阅主题,挂载到消息总线上
* @param msg消息体,携带topic信息和数据载荷
* @param handler消息处理函数,收到到msg时执行
* platform
* |--bus1(topic.001)
* |--node1
* |--[msg1, msg2, msg3,...]
* |--{topic.001, handler1}
* |--{topic.002, handler2}
* |--node2
* |--[msg1, msg2, msg3,...]
* |--{topic.001, handler1}
* |--{topic.003, handler3}
* |--bus2(topic.002)
* |--node1
* |--[]
* |--{topic.001, handler1}
* |--{topic.003, handler3}
* |--bus3(topic.003)
* |--node2
* |--[msgA, msgB, msgC, ...]
* |--{topic.001, handler1}
* |--{topic.003, handler3}
*/
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <thread>
#include <sstream>
#include <iostream>
#include "ldds.h"
/**
* @brief 消息模型
* 模块a[订阅、发布]
* 模块b[订阅、发布]
* 模块c[订阅、发布]
* ...
* 模块x[订阅、发布]
*/
// 模块:监听消息到来,并处理消息
std::thread node_listener(ldds_node_t node) {
while (true) {
int msg_count = ldds_dispatch(node);
if (msg_count > 0) {
printf("msg_count=%d\n", msg_count);
}
usleep(1000);
}
}
void on_adc1_change(ldds_msg_t msg) {
// 处理ADC1数据变化事件
}
void on_adc2_change(ldds_msg_t msg) {
// 处理ADC2数据变化事件
}
// 订阅ADC1_change主题
void sub_adc1(void) {
ldds_node_t node = ldds_new();
ldds_sub(ADC1_node, "ADC1_change", on_adc1_change);
std::thread(node_listener, std::ref(ADC1_node)).detach();
}
// 订阅ADC2_change主题
void sub_adc2(void) {
ldds_node_t node = ldds_new();
ldds_sub(ADC2_node, "ADC2_change", on_adc2_change);
std::thread(node_listener, std::ref(ADC2_node)).detach();
}
// 模拟adc1驱动,读取数据
void adc1_reader(void) {
static int adc_value = 0;
int tmp = random() % 4096;
if (tmp != adc_value) {
adc_value = tmp;
ldds_pub("ADC1_change", &adc_value, strlen(adc_value));
}
}
// 模拟adc2驱动,读取数据
void adc2_reader(void) {
static int adc_value = 0;
int tmp = random() % 4096;
if (tmp != adc_value) {
adc_value = tmp;
ldds_pub("ADC2_change", &adc_value, strlen(adc_value));
}
}
int main(void) {
sub_adc1();
sub_adc2();
while (1) {
adc1_reader();
adc2_reader();
ldds_task_delay(1000 * 1000);
}
return 0;
}
.
├── CMakeLists.txt # idf-5.2.1
├── component.mk # idf-4.3.5
├── demo # 演示用例
│ ├── duration_demo.cxx # 持续时间实例演示
│ ├── hex_demo.cxx # 十六进制实例演示
│ ├── ldds_demo.cxx # 消息总线实例演示
│ ├── makefile # linux下编译管理
│ ├── msg_demo.cxx # 消息体实例演示
│ ├── mutex_demo.cxx # 互斥锁实例演示
│ ├── node_demo.cxx # 消息框架角色节点实例演示
│ ├── payload_demo.cxx # 消息载荷实例演示
│ ├── platform_demo.cxx # 消息平台实例演示
│ ├── rtti_demo.cxx # 类型信息实例演示
│ ├── syncm_demo.cxx # 同步kv表实例演示
│ ├── syncq_demo.cxx # 同步队列实例演示
│ ├── time_demo.cxx # 时间实例演示
│ └── bus_demo.cxx # 消息总线实例演示
├── ldds.cc # LDDS框架c接口实现
├── ldds.h # LDDS框架c接口
├── ldds_bus.h # 消息总线头
├── ldds_cmutex.cc # 互斥锁c接口实现
├── ldds_cmutex.h # 互斥锁c接口
├── ldds_duration.h # 时间统计
├── ldds_hex.h # 十六进制打印
├── ldds_msg.cc # 消息操作c接口实现
├── ldds_msg.h # 消息操作c接口
├── ldds_msgcc.h # 消息定义c++版
├── ldds_mutex.h # 互斥锁
├── ldds_node.h # 消息订阅者节点
├── ldds_payload.h # 消息载荷
├── ldds_platform.h # 消息平台
├── ldds_rtti.h # 类型信息
├── ldds_syncm.h # 同步kv表
├── ldds_syncq.h # 同步队列
├── ldds_task.h # 任务创建、开启
├── ldds_time.h # 开机时间、挂钟时间
├── makefile # 编译libldds.a
└── port
├── freertos # freertos系统兼容
│ ├── ldds_frtos_mutex.h
│ ├── ldds_frtos_task.h
│ └── ldds_frtos_time.h
└── linux # linux系统兼容
├── ldds_linux_mutex.h
└── ldds_linux_time.h