e8ee92110be42644a9ebc637309fc2ffbf893743
DataRouter
轻量级 C 语言数据路由库。发送能力和接收能力分开声明,端口绑定 send_type 和外设 handler 列表。调用 datarouter_send_<id>(data, len) 时自动广播到所有匹配端口。
概念
| 术语 | 说明 |
|---|---|
| 发送能力 (Send Capability) | 编译期声明的可发送报文类型,生成 datarouter_send_<id>(data, len) |
| 接收能力 (Recv Capability) | 编译期声明的可接收报文类型,生成 datarouter_on_recv_<id>(port, data, len) |
| 端口 (Port) | 运行期创建的连接点,包含 send_type + handler 列表 |
| Handler | 用户实现的物理外设发送函数,一个端口可注册多个(默认上限 4) |
快速开始
1. 声明能力
创建自己的 datarouter_config.h(可参考 datarouter_config_template.h):
#define DATAROUTER_SEND_CAPABILITIES \
DATAROUTER_SEND(sensor, "Sensor data report") \
DATAROUTER_SEND(status, "Device status report")
#define DATAROUTER_RECV_CAPABILITIES \
DATAROUTER_RECV(rtcm, "RTCM correction data") \
DATAROUTER_RECV(command, "Remote control command")
库自带默认配置。将你的
datarouter_config.h放到项目目录, 编译时添加-I /path/to/your/config即可覆盖。无需修改库源码。include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(path/to/DataRouter) target_link_libraries(my_app DataRouter)
2. 实现外设发送 handler
static void uart_send(uint32_t port_id, const void *data, size_t len) {
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. 创建端口
datarouter_init();
/* —— 传感器上报:sensor 报文走 UART + TCP —— */
datarouter_port_t tx = datarouter_port_create();
datarouter_port_set_send_type(tx, DATAROUTER_SEND_sensor);
datarouter_port_add_handler(tx, uart_send);
datarouter_port_add_handler(tx, tcp_send);
/* 不指定端口,库自动广播到所有 send_type=sensor 的端口 */
datarouter_send_sensor("temperature:25.3", 16); // → UART + TCP
/* —— 接收:实现回调,外设数据到达后自行调用 —— */
datarouter_on_recv_rtcm(rx_port, data, len);
4. 实现接收回调
void datarouter_on_recv_rtcm(uint32_t port_id, const void *data, size_t len) {
apply_rtcm_correction(data, len);
}
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_send_type(port, int cap_id); // 设置发送类型
int datarouter_port_get_send_type(port); // -1 = 未设置
int datarouter_port_add_handler(port, handler); // 注册外设 handler
int datarouter_port_remove_handler(port, handler); // 移除
void datarouter_port_clear_handlers(port); // 清除全部
int datarouter_port_handler_count(port); // 当前数量
发送触发(每个 SEND 能力生成一个)
int datarouter_send_sensor(const void *data, size_t len); // 0 成功
int datarouter_send_status(const void *data, size_t len); // -1 未初始化
// -2 无匹配端口
不指定端口,库遍历所有端口,send_type 匹配的逐一调用其全部 handler。
接收回调(每个 RECV 能力生成一个声明)
void datarouter_on_recv_rtcm(uint32_t port_id, const void *data, size_t len);
void datarouter_on_recv_command(uint32_t port_id, const void *data, size_t len);
库提供弱符号默认空实现,用户定义同名函数覆盖。
能力元数据(两组独立)
int datarouter_send_cap_count(void);
const char *datarouter_send_cap_name(int cap_id);
const char *datarouter_send_cap_desc(int cap_id);
int datarouter_recv_cap_count(void);
const char *datarouter_recv_cap_name(int cap_id);
const char *datarouter_recv_cap_desc(int cap_id);
路由模型
datarouter_send_sensor("temperature:25.3", 16)
│
├─→ port 0 (send_type=sensor) handlers[0]=uart_send → UART
│ handlers[1]=tcp_send → TCP
└─→ port 1 (send_type=sensor) handlers[0]=can_send → CAN
- 调用
send_<id>(data, len)时,库遍历所有端口,自动匹配send_type - 每个端口可注册多个 handler(一对多广播)
- 同一 handler 可注册到多个端口(多路复用)
- 运行时通过
add_handler/remove_handler/port_delete动态改变路由 - 无任何端口匹配该
send_type时返回 -2
编译
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
当前 22 个测试用例,覆盖端口管理、send_type 与 handler 设置、自动广播路由、接收回调、能力元数据。
文件结构
datarouter_config.h 发送 + 接收能力配置(用户可覆盖)
datarouter.h 公共 API + X-macro 展开
datarouter.c 实现(端口表 + send 遍历)
datarouter_config_template.h 外部配置模板
example.c 使用示例
tests/test_datarouter.c 单元测试(22 用例)
DESIGN.md 详细设计文档(含 PlantUML 图)
TEST_CASES.md 测试用例文档
依赖
- C11 编译器
- CMake ≥ 3.10
- 无第三方库依赖