feat: 添加CM3/4/7的硬件与软件浮点单元构建矩阵,变更api接口为dr_*
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
# DataRouter
|
||||
|
||||
轻量级 C 语言数据路由库。**发送能力和接收能力分开声明**,端口绑定 `send_type` 和外设 handler 列表。调用 `datarouter_send_<id>(data, len)` 时自动广播到所有匹配端口。
|
||||
轻量级 C 语言数据路由库。**发送能力和接收能力分开声明**,端口绑定 `send_type` 和外设 handler 列表。调用 `dr_send_<id>(data, len)` 时自动广播到所有匹配端口。
|
||||
|
||||
## 概念
|
||||
|
||||
| 术语 | 说明 |
|
||||
|------|------|
|
||||
| **发送能力 (Send Capability)** | 编译期声明的可发送报文类型,生成 `datarouter_send_<id>(data, len)` |
|
||||
| **接收能力 (Recv Capability)** | 编译期声明的可接收报文类型,生成 `datarouter_on_recv_<id>(port, data, len)` |
|
||||
| **发送能力 (Send Capability)** | 编译期声明的可发送报文类型,生成 `dr_send_<id>(data, len)` |
|
||||
| **接收能力 (Recv Capability)** | 编译期声明的可接收报文类型,生成 `dr_on_recv_<id>(port, data, len)` |
|
||||
| **端口 (Port)** | 运行期创建的连接点,包含 `send_type` + handler 列表 |
|
||||
| **Handler** | 用户实现的物理外设发送函数,一个端口可注册多个(默认上限 4) |
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
|
||||
### 1. 声明能力
|
||||
|
||||
创建自己的 `datarouter_config.h`(可参考 `datarouter_config_template.h`):
|
||||
创建自己的 `dr_config.h`(可参考 `dr_config_template.h`):
|
||||
|
||||
```c
|
||||
#define DATAROUTER_SEND_CAPABILITIES \
|
||||
DATAROUTER_SEND(sensor, "Sensor data report") \
|
||||
DATAROUTER_SEND(status, "Device status report")
|
||||
#define DR_SEND_CAPABILITIES \
|
||||
DR_SEND(sensor, "Sensor data report") \
|
||||
DR_SEND(status, "Device status report")
|
||||
|
||||
#define DATAROUTER_RECV_CAPABILITIES \
|
||||
DATAROUTER_RECV(rtcm, "RTCM correction data") \
|
||||
DATAROUTER_RECV(command, "Remote control command")
|
||||
#define DR_RECV_CAPABILITIES \
|
||||
DR_RECV(rtcm, "RTCM correction data") \
|
||||
DR_RECV(command, "Remote control command")
|
||||
```
|
||||
|
||||
> 库自带默认配置。将你的 `datarouter_config.h` 放到项目目录,
|
||||
> 库自带默认配置。将你的 `dr_config.h` 放到项目目录,
|
||||
> 编译时添加 `-I /path/to/your/config` 即可覆盖。无需修改库源码。
|
||||
>
|
||||
> ```cmake
|
||||
@@ -51,25 +51,25 @@ static void tcp_send(uint32_t port_id, const void *data, size_t len) {
|
||||
### 3. 创建端口
|
||||
|
||||
```c
|
||||
datarouter_init();
|
||||
dr_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);
|
||||
dr_port_t tx = dr_port_create();
|
||||
dr_port_set_send_type(tx, DR_SEND_sensor);
|
||||
dr_port_add_handler(tx, uart_send);
|
||||
dr_port_add_handler(tx, tcp_send);
|
||||
|
||||
/* 不指定端口,库自动广播到所有 send_type=sensor 的端口 */
|
||||
datarouter_send_sensor("temperature:25.3", 16); // → UART + TCP
|
||||
dr_send_sensor("temperature:25.3", 16); // → UART + TCP
|
||||
|
||||
/* —— 接收:实现回调,外设数据到达后自行调用 —— */
|
||||
datarouter_on_recv_rtcm(rx_port, data, len);
|
||||
dr_on_recv_rtcm(rx_port, data, len);
|
||||
```
|
||||
|
||||
### 4. 实现接收回调
|
||||
|
||||
```c
|
||||
void datarouter_on_recv_rtcm(uint32_t port_id, const void *data, size_t len) {
|
||||
void dr_on_recv_rtcm(uint32_t port_id, const void *data, size_t len) {
|
||||
apply_rtcm_correction(data, len);
|
||||
}
|
||||
```
|
||||
@@ -79,30 +79,30 @@ void datarouter_on_recv_rtcm(uint32_t port_id, const void *data, size_t len) {
|
||||
### 初始化
|
||||
|
||||
```c
|
||||
void datarouter_init(void); // 幂等初始化
|
||||
void datarouter_reset(void); // 重置全部状态
|
||||
void dr_init(void); // 幂等初始化
|
||||
void dr_reset(void); // 重置全部状态
|
||||
```
|
||||
|
||||
### 端口管理
|
||||
|
||||
```c
|
||||
datarouter_port_t datarouter_port_create(void); // 创建端口
|
||||
void datarouter_port_delete(datarouter_port_t port); // 删除
|
||||
dr_port_t dr_port_create(void); // 创建端口
|
||||
void dr_port_delete(dr_port_t port); // 删除
|
||||
|
||||
void datarouter_port_set_send_type(port, int cap_id); // 设置发送类型
|
||||
int datarouter_port_get_send_type(port); // -1 = 未设置
|
||||
void dr_port_set_send_type(port, int cap_id); // 设置发送类型
|
||||
int dr_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); // 当前数量
|
||||
int dr_port_add_handler(port, handler); // 注册外设 handler
|
||||
int dr_port_remove_handler(port, handler); // 移除
|
||||
void dr_port_clear_handlers(port); // 清除全部
|
||||
int dr_port_handler_count(port); // 当前数量
|
||||
```
|
||||
|
||||
### 发送触发(每个 SEND 能力生成一个)
|
||||
|
||||
```c
|
||||
int datarouter_send_sensor(const void *data, size_t len); // 0 成功
|
||||
int datarouter_send_status(const void *data, size_t len); // -1 未初始化
|
||||
int dr_send_sensor(const void *data, size_t len); // 0 成功
|
||||
int dr_send_status(const void *data, size_t len); // -1 未初始化
|
||||
// -2 无匹配端口
|
||||
```
|
||||
|
||||
@@ -111,8 +111,8 @@ int datarouter_send_status(const void *data, size_t len); // -1 未初始化
|
||||
### 接收回调(每个 RECV 能力生成一个声明)
|
||||
|
||||
```c
|
||||
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);
|
||||
void dr_on_recv_rtcm(uint32_t port_id, const void *data, size_t len);
|
||||
void dr_on_recv_command(uint32_t port_id, const void *data, size_t len);
|
||||
```
|
||||
|
||||
库提供弱符号默认空实现,用户定义同名函数覆盖。
|
||||
@@ -120,19 +120,19 @@ void datarouter_on_recv_command(uint32_t port_id, const void *data, size_t len);
|
||||
### 能力元数据(两组独立)
|
||||
|
||||
```c
|
||||
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 dr_send_cap_count(void);
|
||||
const char *dr_send_cap_name(int cap_id);
|
||||
const char *dr_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);
|
||||
int dr_recv_cap_count(void);
|
||||
const char *dr_recv_cap_name(int cap_id);
|
||||
const char *dr_recv_cap_desc(int cap_id);
|
||||
```
|
||||
|
||||
## 路由模型
|
||||
|
||||
```
|
||||
datarouter_send_sensor("temperature:25.3", 16)
|
||||
dr_send_sensor("temperature:25.3", 16)
|
||||
│
|
||||
├─→ port 0 (send_type=sensor) handlers[0]=uart_send → UART
|
||||
│ handlers[1]=tcp_send → TCP
|
||||
@@ -155,9 +155,65 @@ cmake --build build
|
||||
可选配置:
|
||||
|
||||
```bash
|
||||
cmake -DCMAKE_C_FLAGS="-DDATAROUTER_MAX_PORTS=128 -DDATAROUTER_MAX_HANDLERS_PER_PORT=8"
|
||||
cmake -DCMAKE_C_FLAGS="-DDR_MAX_PORTS=128 -DDR_MAX_HANDLERS_PER_PORT=8"
|
||||
```
|
||||
|
||||
## 嵌入式 / Cortex-M 构建
|
||||
|
||||
库支持 `arm-none-eabi-gcc` 交叉编译,提供 **7 个 CMake preset** 覆盖常见 Cortex-M 目标:
|
||||
|
||||
```bash
|
||||
# 列出所有 preset
|
||||
cmake --list-presets
|
||||
|
||||
# Cortex-M3(软浮点)
|
||||
cmake --preset cm3
|
||||
cmake --build --preset cm3
|
||||
|
||||
# Cortex-M4F(硬件浮点,单精度)
|
||||
cmake --preset cm4-hard
|
||||
cmake --build --preset cm4-hard
|
||||
|
||||
# Cortex-M7F(硬件浮点,双精度)
|
||||
cmake --preset cm7-hard-dp
|
||||
cmake --build --preset cm7-hard-dp
|
||||
```
|
||||
|
||||
> 使用 preset 编译需要 `arm-none-eabi-gcc` 在 PATH 中。
|
||||
> 各 preset 均启用 `DR_SOURCE_ONLY` 模式——只提供源文件路径,
|
||||
> 你需要将 `datarouter.c` 加入自己的 target 以继承项目编译标志:
|
||||
|
||||
```cmake
|
||||
# 你的 CMakeLists.txt
|
||||
set(DR_SOURCE_ONLY ON)
|
||||
FetchContent_MakeAvailable(datarouter)
|
||||
target_sources(my_app PRIVATE ${datarouter_SOURCE_DIR}/datarouter.c)
|
||||
target_include_directories(my_app PRIVATE ${datarouter_SOURCE_DIR})
|
||||
```
|
||||
|
||||
### 编译兼容性矩阵
|
||||
|
||||
启用 `DR_COMPILE_CHECK` 可自动检测 `arm-none-eabi-gcc` 并对 CM3/CM4/CM7
|
||||
各变体执行编译验证:
|
||||
|
||||
```bash
|
||||
cmake -B build-check -DDR_COMPILE_CHECK=ON
|
||||
cmake --build build-check # 生成 check_cm3, check_cm4-hard, … 等 target
|
||||
# 或单独检查某个变体:
|
||||
make check_cm7-hard-dp
|
||||
```
|
||||
|
||||
### 内置 CMake Preset 列表
|
||||
|
||||
| Preset | 目标 | FPU | ABI |
|
||||
|--------|------|-----|-----|
|
||||
| `cm3` | Cortex-M3 | 无 | soft |
|
||||
| `cm4-soft` | Cortex-M4 | 无 | soft |
|
||||
| `cm4-hard` | Cortex-M4F | FPv4-SP-D16 | hard |
|
||||
| `cm7-soft` | Cortex-M7 | 无 | soft |
|
||||
| `cm7-hard-sp` | Cortex-M7F | FPv5-SP-D16 | hard |
|
||||
| `cm7-hard-dp` | Cortex-M7F | FPv5-D16 | hard |
|
||||
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
@@ -172,10 +228,10 @@ ctest --test-dir build
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
datarouter_config.h 发送 + 接收能力配置(用户可覆盖)
|
||||
dr_config.h 发送 + 接收能力配置(用户可覆盖)
|
||||
datarouter.h 公共 API + X-macro 展开
|
||||
datarouter.c 实现(端口表 + send 遍历)
|
||||
datarouter_config_template.h 外部配置模板
|
||||
dr_config_template.h 外部配置模板
|
||||
example.c 使用示例
|
||||
tests/test_datarouter.c 单元测试(22 用例)
|
||||
DESIGN.md 详细设计文档(含 PlantUML 图)
|
||||
|
||||
Reference in New Issue
Block a user