RTU_ALL_AI/docs/public/libdatacenter/API-libdatacenter.md

12 KiB
Raw Blame History

API-libdatacenter — 数据中心模块

版本: v3.0
日期: 2026-07-07
状态: 已实现(对齐 RTU 原工程 v1+v2 全部功能)


1. 模块概述

libdatacenter 是 RTU 通讯装置的核心数据中间层,负责:

功能 说明
信号注册与管理 5 种信号类型out/in/yk/ao/param统一存储和 XXH3 哈希索引
回路阻断 通过 module_id 实现"修改信号的模块不收到自己的回调"
延迟变化检测 out 信号采用脏标记 + 100ms 批量检测,避免频繁回调
SBO 控制流程 支持直控Direct和选控Select-Before-Operate两种模式
参数元数据 min/max/step/unit 值校验
配置文件持久化 通过 libxml C 接口读写 param.xml/self_param.xml
事件队列 SOE 事件、扰动数据、故障录波三类队列(支持多消费者)
异步执行 yk/ao/param 异步控制 + 超时检测 + 取消
命令调试 通过 libcmd 注册 datacenter 命令,交互式查看信号

架构依赖

libmy_xxhash → libxml → libcmd
                 ↘      ↙
              libdatacenter

2. 数据结构

2.1 控制类型

typedef enum
{
    DC_CTRL_NONE   = 0,   /**< 无控制 */
    DC_CTRL_DIRECT = 1,   /**< 直控(直接执行) */
    DC_CTRL_SBO    = 2    /**< 选控Select-Before-Operate */
} dc_ctrl_type_t;

2.2 控制步骤

typedef enum
{
    DC_STEP_READY  = 0,   /**< 就绪 */
    DC_STEP_SELECT = 1,   /**< 选择 */
    DC_STEP_DIRECT = 2,   /**< 执行 */
    DC_STEP_CANCEL = 3    /**< 取消 */
} dc_ctrl_step_t;

2.3 SBO 状态转换

READY ──→ SELECT锁住信号暂存值到 ctrl.p_data
  │           │
  │           ├──→ DIRECT返校比对 → 写入 → ctrl.step = READY
  │           │
  │           └──→ CANCEL回退ctrl.step = READY
  │
  └──→ DIRECT直控直接写入

2.4 控制上下文

typedef struct
{
    uint8_t step;       /**< 当前步骤 */
    uint8_t type;       /**< 控制类型 */
    uint8_t data_type;  /**< 数据类型 */
    uint8_t reserved;   /**< 保留 */
    void   *p_data;     /**< SELECT时暂存选择值DIRECT时返校比对 */
} dc_ctrl_t;

2.5 参数元数据

typedef struct
{
    float min;          /**< 最小值 */
    float max;          /**< 最大值 */
    float step;         /**< 步长 */
    char  unit[32];     /**< 单位 */
} dc_param_meta_t;

2.6 错误码

名称 说明
0 DC_OK 成功
-1 DC_ERR_PARAM 参数错误
-2 DC_ERR_NOTFOUND 信号不存在
-3 DC_ERR_TYPE 数据类型不匹配
-4 DC_ERR_STEP SBO 步骤错误
-5 DC_ERR_VAL 值校验失败
-6 DC_ERR_TIMEOUT 异步超时
-7 DC_ERR_BUSY
-8 DC_ERR_MEM 内存不足
-9 DC_ERR_FULL 队列已满
-10 DC_ERR_LOCKED 已锁定
-11 DC_ERR_EXISTS 重复注册
-12 DC_ERR_CANCEL 已取消

3. 接口函数

3.1 模块生命周期

函数 说明
dc_init(cfg_dir) 初始化,自动加载 param.xml
dc_cleanup() 清理所有资源
dc_run_100ms() 每100msout变化检测 + 事件弹出 + 异步超时
dc_run_1000ms() 每1000ms参数变更检测 → 写 self_param.xml

3.2 Out 信号(遥测/遥信)

函数 说明
dc_signal_out(saddr, desc, data_type, p_data, module_id) 注册输出信号
dc_signal_out_with_callback(..., cb, module_id) 注册 + 延迟变化回调
dc_signal_out_link_with_callback(saddr, pp_data, cb, module_id) 链接已有信号
dc_set_out_signal_val(saddr, set_data, module_id) 设值(脏标记 + 延迟回调)

3.3 In 信号(输入信号,链接 out

函数 说明
dc_signal_in(saddr, desc, link_saddr, pp_data, module_id) 注册并关联 out
dc_signal_in_with_callback(..., cb, module_id) 注册 + 回调(挂在 out 上)

3.4 YK 信号(遥控)

函数 说明
dc_signal_yk(...) 注册遥控信号
dc_signal_yk_link_with_callback(...) 链接已有
dc_signal_yk_set_status(saddr, step, ctrl, p_data, module_id) 同步控制
dc_yk_exec_async(saddr, step, ctrl, p_data, module_id, result_cb, arg, timeout, req_id) 异步控制
dc_yk_set_result(req_id, result, err) 异步结果通知
dc_yk_cancel_async(req_id) 取消异步
dc_yk_register_exec_cb(saddr, exec_cb, ctx) 注册执行回调

3.5 AO 信号(模拟输出)

函数 说明
dc_signal_ao(...) 注册 AO 信号
dc_signal_ao_link_with_callback(...) 链接已有
dc_signal_ao_set_val(saddr, step, ctrl, p_data, module_id) 同步控制SBO + 值校验)
dc_signal_ao_set_val_without_check(...) 无校验设值
dc_ao_exec_async(...) 异步控制
dc_ao_set_result(...) 异步结果通知
dc_ao_cancel_async(...) 取消异步
dc_ao_register_exec_cb(...) 注册执行回调

3.6 Param 信号(定值,多区)

函数 说明
dc_signal_param(saddr, desc, data_type, ctrl_type, pp_data, num_zones, cb, module_id) 注册参数
dc_signal_param_link_with_callback(...) 链接已有
dc_signal_param_set_val(saddr, step, ctrl, zone, p_data, module_id) 同步设值
dc_signal_param_set_val_without_check(...) 无校验设值
dc_param_exec_async(...) 异步控制
dc_param_set_result(...) 异步结果通知
dc_param_cancel_async(...) 取消异步
dc_param_register_exec_cb(...) 注册执行回调

3.7 信号查询

函数 说明
dc_get_out_signal_info(saddr, desc, desc_len, data_type, pp_data) 查询 out
dc_get_in_signal_info(...) 查询 in
dc_get_ao_signal_info(saddr, desc, desc_len, data_type, p_meta, ctrl_type, pp_data) 查询 AO含元数据
dc_get_param_signal_info(saddr, desc, desc_len, data_type, p_meta, ctrl_type, p_data_array, p_count) 查询 Param多区
dc_get_yk_signal_info(...) 查询 YK
dc_get_signal_val(p_data, data_type, buf, buf_len) 值 → 字符串
dc_get_signal_count(type_str) 按类型统计
dc_get_signal_info_by_id(type_str, id, ...) 按 ID 查询

3.8 事件队列

函数 说明
dc_event_queue_push(p_soe) SOE 入队
dc_event_register_queue_pop(cb) 注册 SOE 消费回调
dc_disturb_dd_queue_push(p_dd) 扰动数据入队
dc_disturb_dd_register_queue_pop(cb) 注册扰动消费回调
dc_fault_queue_push(p_fault) 故障数据入队
dc_fault_register_queue_pop(cb) 注册故障消费回调

3.9 类型工具

函数 说明
dc_get_type_name(data_type) ID → 名称35 → "uint32_t"
dc_get_type_id_by_name(name) 名称 → ID"float" → 38
dc_get_type_len(data_type) 获取字节长度
dc_create_data(data_type) / dc_destroy_data(p_data, data_type) 类型感知的分配/释放
dc_copy_val(dst, src, data_type) / dc_compare_val(p1, p2, data_type) 类型感知的复制/比较
dc_set_val_from_str(p_data, data_type, str) 字符串 → 值

3.10 配置与异步管理

函数 说明
dc_param_cfg_changed() 查询是否有未保存变更
dc_async_pending_count() 异步请求 pending 数
dc_async_set_default_timeout(ms) 全局默认超时
dc_async_set_timeout_yk/ao/param(ms) 各类型默认超时
dc_save_out_signals_xml(path) 导出 out 信号到 XML

4. 使用示例

#include "myDatacenter.h"
#include <stdio.h>

static void on_out_changed(const char *saddr, uint8_t data_type,
                            const void *p_new, const void *p_old)
{
    printf("out %s: %d → %d\n", saddr, *(int *)p_old, *(int *)p_new);
}

static void on_yk_changed(const char *saddr, dc_ctrl_step_t step,
                           uint8_t data_type, uint8_t zone,
                           const void *p_data)
{
    printf("yk %s step=%d val=%d\n", saddr, step, *(uint8_t *)p_data);
}

int main(void)
{
    /* 初始化,自动加载 param.xml */
    dc_init("/etc/rtu/config/");

    /* 注册 out 信号 */
    int yc_val = 0;
    dc_signal_out("RPC1:YC:1:val", "母线电压", DATA_TYPE_S32,
                  &yc_val, "protocol_104");

    /* 另一个模块链接 out 信号并注册回调 */
    void *p_linked = NULL;
    dc_signal_out_link_with_callback("RPC1:YC:1:val", &p_linked,
                                      on_out_changed, "web_server");

    /* 注册 yk 信号(直控模式) */
    uint8_t yk_val = 0;
    dc_signal_yk("RPC1:YK:1:val", "开关合闸", DATA_TYPE_U8,
                 DC_CTRL_DIRECT, &yk_val, on_yk_changed, "protocol_104");

    /* 修改 out 信号值回路阻断protocol_104 自身的回调不会被触发) */
    yc_val = 220;
    dc_set_out_signal_val("RPC1:YC:1:val", &yc_val, "protocol_104");

    /* 100ms 周期on_out_changed 被调用 */
    dc_run_100ms();

    /* YK 直控执行同步回调on_yk_changed 立即触发) */
    dc_ctrl_t ctrl = {0};
    ctrl.type = DC_CTRL_DIRECT;
    ctrl.data_type = DATA_TYPE_U8;
    uint8_t new_val = 1;
    dc_signal_yk_set_status("RPC1:YK:1:val", DC_STEP_DIRECT,
                            &ctrl, &new_val, "web_server");

    dc_cleanup();
    return 0;
}

5. 依赖关系

依赖 模块 用途
myBase.h 基础类型定义DATA_TYPE_* 宏)
myLog.h 日志输出
libmy_xxhash XXH3_128bits 哈希查找O(1)
libxml 纯 C 接口 XML 解析param.xml/self_param.xml
libcmd 命令注册(datacenter 调试面板)

6. 源文件组成15 文件,对齐 RTU 原工程)

文件 职责
inc/myDatacenter.h 纯 C 对外接口60+ API
src/dc_internal.h C++ 内部声明(哈希/信号表/异步队列)
src/dc_core.cpp 全局变量 + XXH128 哈希 + dc_init/run
src/dc_signal_out.cpp Out 信号注册/链接/设值
src/dc_signal_in.cpp In 信号注册(关联 out
src/dc_signal_yk.cpp YK 注册 + 同步/异步控制
src/dc_signal_ao.cpp AO 注册 + 同步/异步控制 + SBO
src/dc_signal_param.cpp Param 多区定值 + 同步/异步控制
src/dc_signal_query.cpp 全部 get_xxx_info 函数
src/dc_signal_util.cpp 19 种类型工具函数
src/dc_signal_check.cpp SBO 校验 + 值校验 + YK 校验
src/dc_signal_show.cpp 命令注册 + XML 导出
src/dc_param_cfg.cpp param.xml 解析 + self_param.xml 保存
src/dc_event.cpp SOE/扰动/故障事件队列
src/dc_async.cpp 异步请求队列(入队/超时/取消/清理)
src/dc_api_wrap.cpp C API 包装get_type_name 等)

7. 新旧工程差异

维度 RTU v1 RTU v2 新工程
接口语言 C++ (std::string) 纯 C (const char*) 纯 C + Allman 风格
哈希 XXH128 multimap 同 v1 unordered_map + XXH128 hasher
参数文件 tinyxml2 嵌入 同 v1 libxml C 接口
异步执行 _exec_async 系列 _exec_async 系列
回路阻断
SBO 流程
多区定值
错误码 -1/0 enum dc_error_t enum dc_error_t12种
命令调试 cmd_dc CMD_REGISTER_Clibcmd
文件数 13 .cpp 8 .cpp 15 .cpp按功能拆分