# DataRouter 轻量级 C 语言数据路由库。编译期声明报文类型,运行期将端口绑定到物理外设发送函数,实现一对多广播路由。 ## 概念 | 术语 | 说明 | |------|------| | **通道 (Channel)** | 编译期声明的报文类型(如 `sensor` / `status` / `control`) | | **端口 (Port)** | 运行期创建的连接点,绑定一个报文类型和 N 个外设发送 handler | | **路由** | 将报文类型连接到物理外设发送函数的过程 | | **Handler** | 用户实现的物理外设发送函数,一个端口可注册多个(默认上限 4) | ## 快速开始 ### 1. 声明报文类型 编辑 `datarouter_config.h`: ```c #define DATAROUTER_CHANNELS \ DATAROUTER_CHANNEL(sensor, "Sensor data") \ DATAROUTER_CHANNEL(status, "Status report") \ DATAROUTER_CHANNEL(control, "Control command") ``` ### 2. 实现外设发送 handler ```c 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 ```c 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. 实现接收回调 ```c 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 一览 ### 初始化 ```c void datarouter_init(void); // 初始化(幂等) void datarouter_reset(void); // 重置全部状态 ``` ### 端口管理 ```c 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 自动生成) ```c 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 ``` ### 接收回调(每通道一个,用户实现) ```c 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); ``` 库提供弱符号默认空实现,用户定义同名函数即可覆盖。 ### 通道元数据 ```c 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 ## 编译 ```bash cmake -S . -B build cmake --build build ``` 可选配置项: ```bash cmake -DCMAKE_C_FLAGS="-DDATAROUTER_MAX_PORTS=128 -DDATAROUTER_MAX_HANDLERS_PER_PORT=8" ``` ## 测试 ```bash 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 - 无第三方库依赖