/** * @file datarouter.h * @brief 数据路由库 —— 公共接口 * * ## 概念 * * - **发送能力**:编译期声明的可发送报文类型,生成 dr_send_(data, len) * - **接收能力**:编译期声明的可接收报文类型,生成 dr_on_recv_(port, data, len) * - **端口**:运行期连接点,包含 send_type + recv_type + handler 列表 * * ## 发送路由 * * dr_send_(data, len) 遍历所有端口,找到 send_type 匹配的端口, * 逐一调用其全部 handler,无需指定从哪个端口发送。 * * ## 接收路由 * * 外设(UART / SPI / CAN)收到数据后,调用 dr_port_dispatch(port, data, len), * 库根据端口的 recv_type 自动查表调用对应的 dr_on_recv_(),无需手动 if/else。 */ #ifndef DR_H #define DR_H #include #include #if defined(__has_include) # if __has_include() # include # else # include "datarouter_config.h" # endif #else # include "datarouter_config.h" #endif #ifdef __cplusplus extern "C" { #endif /* ========== 发送能力枚举 ========== */ enum dr_send_cap { #define DR_SEND(id, desc) DR_SEND_##id, DR_SEND_CAPABILITIES #undef DR_SEND DR_SEND_CAP_COUNT }; /* ========== 接收能力枚举 ========== */ enum dr_recv_cap { #define DR_RECV(id, desc) DR_RECV_##id, DR_RECV_CAPABILITIES #undef DR_RECV DR_RECV_CAP_COUNT }; /* ========== 外设发送 handler ========== */ typedef void (*dr_send_handler_t)(uint32_t port_id, const void *data, size_t len); #ifndef DR_MAX_HANDLERS_PER_PORT #define DR_MAX_HANDLERS_PER_PORT 4 #endif /* ========== 发送触发函数 ========== */ #define DR_SEND(id, desc) \ int dr_send_##id(const void *data, size_t len); DR_SEND_CAPABILITIES #undef DR_SEND /* ========== 接收回调声明 ========== */ #define DR_RECV(id, desc) \ void dr_on_recv_##id(uint32_t port_id, const void *data, size_t len); DR_RECV_CAPABILITIES #undef DR_RECV /* ========== 端口管理 API ========== */ typedef int32_t dr_port_t; #define DR_INVALID_PORT ((dr_port_t)-1) void dr_init(void); void dr_reset(void); dr_port_t dr_port_create(void); void dr_port_delete(dr_port_t port); void dr_port_set_send_type(dr_port_t port, int cap_id); int dr_port_get_send_type(dr_port_t port); void dr_port_set_recv_type(dr_port_t port, int cap_id); int dr_port_get_recv_type(dr_port_t port); int dr_port_add_handler(dr_port_t port, dr_send_handler_t handler); int dr_port_remove_handler(dr_port_t port, dr_send_handler_t handler); void dr_port_clear_handlers(dr_port_t port); int dr_port_handler_count(dr_port_t port); /** * @brief 按端口绑定的 recv_type 自动路由到对应的 dr_on_recv_() 回调 * * 外设中断中收到数据后调用此函数,无需自己写 if/else 判断报文类型。 * 库通过 X-macro 生成函数指针表,直接查表调用,零分支预测开销。 * * @param[in] port 接收端口 ID * @param[in] data 数据缓冲区 * @param[in] len 数据长度 */ void dr_port_dispatch(dr_port_t port, const void *data, size_t len); /* ========== 能力元数据查询 ========== */ 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 dr_recv_cap_count(void); const char *dr_recv_cap_name(int cap_id); const char *dr_recv_cap_desc(int cap_id); #ifdef __cplusplus } #endif #endif /* DR_H */