Files
DataRouter/README.md
T
2026-07-26 01:46:47 +08:00

4.7 KiB
Raw Blame History

DataRouter

轻量级 C 语言数据路由库。编译期声明报文类型,运行期将端口绑定到物理外设发送函数,实现一对多广播路由。

概念

术语 说明
通道 (Channel) 编译期声明的报文类型(如 sensor / status / control)
端口 (Port) 运行期创建的连接点,绑定一个报文类型和 N 个外设发送 handler
路由 将报文类型连接到物理外设发送函数的过程
Handler 用户实现的物理外设发送函数,一个端口可注册多个(默认上限 4)

快速开始

1. 声明报文类型

编辑 datarouter_config.h:

#define DATAROUTER_CHANNELS \
    DATAROUTER_CHANNEL(sensor,  "Sensor data")    \
    DATAROUTER_CHANNEL(status,  "Status report")  \
    DATAROUTER_CHANNEL(control, "Control command")

2. 实现外设发送 handler

static void uart_send(uint32_t port_id, const void *data, size_t len) {
    /* 调用具体外设 API 发送数据 */
    HAL_UART_Transmit(&huart1, data, len, 1000);
}

static void tcp_send(uint32_t port_id, const void *data, size_t len) {
    send(tcp_socket, data, len, 0);
}

3. 创建端口并注册 handler

datarouter_init();

datarouter_port_t p = datarouter_port_create();
datarouter_port_set_type(p, DATAROUTER_CHANNEL_sensor);

/* 一个端口同时路由到两个外设 */
datarouter_port_add_handler(p, uart_send);
datarouter_port_add_handler(p, tcp_send);

/* 发送 → 同时走 UART 和 TCP */
datarouter_send_sensor(p, "temperature:25.3", 16);

4. 实现接收回调

void datarouter_on_recv_sensor(uint32_t port_id, const void *data, size_t len) {
    printf("received sensor data: %.*s\n", (int)len, (const char *)data);
}

API 一览

初始化

void datarouter_init(void);   // 初始化(幂等)
void datarouter_reset(void);  // 重置全部状态

端口管理

datarouter_port_t datarouter_port_create(void);       // 创建端口
void  datarouter_port_delete(datarouter_port_t port);  // 删除端口
void  datarouter_port_set_type(port, int channel_id);  // 设置报文类型
int   datarouter_port_get_type(port);                  // 获取报文类型
int   datarouter_port_add_handler(port, handler);      // 注册外设 handler
int   datarouter_port_remove_handler(port, handler);   // 移除 handler
void  datarouter_port_clear_handlers(port);            // 清除全部 handler
int   datarouter_port_handler_count(port);             // handler 数量

发送触发(每通道一个,X-macro 自动生成)

int datarouter_send_sensor(port, data, len);    // 返回值:0 成功 / -1 未初始化
int datarouter_send_status(port, data, len);    //        -2 端口无效
int datarouter_send_control(port, data, len);   //        -3 类型不匹配
                                                //        -4 无 handler

接收回调(每通道一个,用户实现)

void datarouter_on_recv_sensor(uint32_t port_id, const void *data, size_t len);
void datarouter_on_recv_status(uint32_t port_id, const void *data, size_t len);
void datarouter_on_recv_control(uint32_t port_id, const void *data, size_t len);

库提供弱符号默认空实现,用户定义同名函数即可覆盖。

通道元数据

int         datarouter_channel_count(void);
const char *datarouter_channel_name(int channel_id);
const char *datarouter_channel_desc(int channel_id);

路由模型

send_sensor(port, data, len)
  │
  ├─→ handler[0] = uart_send  → UART 外设
  ├─→ handler[1] = tcp_send   → TCP 外设
  └─→ handler[2] = can_send   → CAN 外设
  • 一个端口可注册多个 handler(一对多广播)
  • 同一 handler 可注册到多个端口(多路复用)
  • 运行时通过 add_handler / remove_handler 动态改变路由
  • 清空 handler 后发送返回 -4

编译

cmake -S . -B build
cmake --build build

可选配置项:

cmake -DCMAKE_C_FLAGS="-DDATAROUTER_MAX_PORTS=128 -DDATAROUTER_MAX_HANDLERS_PER_PORT=8"

测试

cmake --build build
ctest --test-dir build
# 或直接运行
./build/test_datarouter

当前 36 个测试用例,覆盖端口管理、类型、handler 增删、一对多广播、接收回调、错误边界。

文件结构

datarouter_config.h   报文类型配置(用户编辑)
datarouter.h          公共 API + X-macro 展开
datarouter.c          实现(端口表 + handler 调用)
example.c             使用示例
tests/test_datarouter.c  单元测试
DESIGN.md             详细设计文档
TEST_CASES.md         测试用例文档

依赖

  • C11 编译器
  • CMake ≥ 3.10
  • 无第三方库依赖