RTU/claude/工程/libiec61850s模块分析.md

9.5 KiB
Raw Blame History

libiec61850s 模块分析

日期2026-06-10


1. 模块概览

libiec61850s 是 IEC 61850 MMS 服务端的应用线程模块(app_iec61850s),属于系统层的第 9 号线程。它作为桥接层,连接三个子系统:

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│   DataCenter    │ ←→  │  libiec61850s    │ ←→  │    libmms_s     │
│  (信号数据中心)   │     │  (应用线程/桥接层)  │     │  (MMS 服务端封装) │
└─────────────────┘     └──────────────────┘     └─────────────────┘
                                ↕
                      ┌──────────────────┐
                      │  mms_s.xml 配置   │
                      └──────────────────┘

目录结构

src/system/libiec61850s/
├── inc/
│   ├── iec61850s.h       # 头文件(包含 mySystem/myMms_s 等)
│   └── parse_xml.h       # XML 配置解析类型 + 接口
└── src/
    ├── iec61850s.cpp     # 应用线程主逻辑(~487 行)
    └── parse_xml.cpp     # mms_s.xml 解析(~129 行)

2. 应用线程模型

与所有 app 线程一致libiec61850s 遵循 init1 → init2 → fun_cb 三段式:

阶段 函数 主要工作
init1 app_iec61850s_init1() 解析配置、注册回调
init2 app_iec61850s_init2() 初始化信号、启动 MMS 服务器
fun_cb app_iec61850s() 主循环3 定时器,当前空闲)

2.1 init1 流程(iec61850s.cpp:392

1. get_base_path()                              → 获取进程目录
2. parse_mms_xml("config/MMS/mms_s.xml")        → 解析 XML 配置
3. mms_s_dbg_switch(false)                      → 关闭调试
4. mms_s_file_path_set(base_path)               → 设置文件根目录
5. mms_s_value_update_register(&cb)             → 注册值更新回调

2.2 init2 流程(iec61850s.cpp:421

1. iec61850s_signals_init()                     → 初始化五类信号
2. mms_s_init("config/MMS/PCS.icd", 102)        → 启动 MMS 服务器

2.3 主循环(iec61850s.cpp:446

三个定时器事件(EV_TIMER1/2/3)当前均为空闲,仅 EV_TIMER3run_cnt++。信号驱动的工作全部通过 libmms_s 的内部线程和 DataCenter 回调完成——本线程主要作为容器,维护 MMS 服务器的生命周期。


3. 配置解析子系统(parse_xml.cpp

3.1 XML 结构mms_s.xml

<Config>
    <St>      <!-- 遥信信号 -->
        <Signal link="st.0" />
    </St>
    <Mx>      <!-- 遥测信号 -->
        <Signal link="mx.0" />
    </Mx>
    <Co>      <!-- 遥控信号 -->
        <Signal link="co.0" />
    </Co>
    <Ao>      <!-- 定值信号 -->
        <Signal link="ao.0" />
    </Ao>
    <Param>   <!-- 参数信号 -->
        <Signal link="param.0" />
    </Param>
</Config>

3.2 数据结构

typedef struct {
    std::vector<stru_mms_s_signal_base> vec_st;    // 遥信
    std::vector<stru_mms_s_signal_base> vec_mx;    // 遥测
    std::vector<stru_mms_s_signal_base> vec_co;    // 遥控
    std::vector<stru_mms_s_signal_base> vec_ao;    // 定值
    std::vector<stru_mms_s_signal_base> vec_param; // 参数
} stru_mms_cfg;

每个 Signal 只需要 linksAddr属性typectrl_model 在后续从 DataCenter 获取。


4. 五类信号初始化

iec61850s_signals_init() 按顺序初始化五类信号(iec61850s.cpp:347

4.1 遥信ST初始化

for each st signal:
    dc_signal_out_link_with_callback(saddr, &p_data, iec61850s_st_mx_change_callback)

将 DataCenter 的 out 信号与本地指针绑定,注册变化回调 iec61850s_st_mx_change_callback

4.2 遥测MX初始化

逻辑与 ST 完全一致,共用同一个回调函数。

4.3 ST/MX 变化回调

iec61850s_st_mx_change_callback(saddr, type, p_data, p_last_data)
    
dc_get_signal_val(p_data, type)  获取当前值字符串
    
g_mms_s_value_update_cb(saddr, val)   更新 MMS 模型中的 DA 

数据流向:DataCenter 信号变化 → 回调 → libmms_s::mms_s_value_update() → IedServer 模型更新

4.4 遥控CO初始化

for each co signal:
    dc_get_yk_signal_info(saddr, desc, type, ctrl_model, &p_data)
    ↓
mms_s_control_register(&g_vec_control, iec61850s_control_callback)

控制执行时,mms_s_control.cppcontrol_handler() 会触发 iec61850s_control_callback(),根据 ctrl_model 调用 DataCenter 的 dc_signal_yk_set_status()

ctrl_model 映射

MMS Control Model DataCenter 动作
DIRECT_NORMAL / DIRECT_ENHANCED SIGNAL_CTRL_TYPE::DIRECT_NORMALdc_signal_yk_set_status(DIRECT)
SBO_NORMAL / SBO_ENHANCED SIGNAL_CTRL_TYPE::SBO_NORMAL → select + direct 两步
STATUS_ONLY 仅日志,不操作

4.5 定值AO初始化

for each ao signal:
    dc_get_ao_signal_info(saddr, desc, type, null, ctrl_model, &p_data, null)
    ↓
mms_s_setting_register(&g_vec_setting, iec61850s_setting_callback)

客户端写定值时,mms_s_setting.cppwriteAccessHandler() 校验通过后触发 iec61850s_setting_callback(),调用 dc_signal_ao_set_val()

4.6 参数Param初始化

for each param signal:
    dc_get_param_signal_info(saddr, desc, type, null, ctrl_model, &p_data_vec, null)
    ↓
mms_s_param_register(&g_vec_param, iec61850s_param_callback)

参数支持多定值区(p_data[MMS_S_PARAM_MAX],最大 16 组)。客户端确认编辑后,edit_sg_confirmation_handler() 触发 iec61850s_param_callback(),调用 dc_signal_param_set_val(),传入 setting_zone 索引。


5. 完整数据流向

5.1 上行数据RTU → 客户端)

DataCenter 信号变化
  → iec61850s_st_mx_change_callback()
    → g_mms_s_value_update_cb(saddr, val)
      → mms_s_value_update() [mms_s_value.cpp]
        → IedServer_update*AttributeValue()
          → libiec61850 内部触发报告(根据 TrgOps 配置)
            → MMS 报告上送到客户端

5.2 下行数据(客户端 → RTU

控制

客户端 Select/Operate
  → libiec61850 → control_handler() [mms_s_control.cpp]
    → iec61850s_control_callback()
      → dc_signal_yk_set_status()

定值

客户端 Write SP
  → libiec61850 → writeAccessHandler() [mms_s_setting.cpp]
    → 值校验(范围/步长)
      → iec61850s_setting_callback()
        → dc_signal_ao_set_val()

参数(定值组)

客户端切换定值组
  → libiec61850 → param_active_sg_changed_handler() [mms_s_param.cpp]
    → param_load_active_sg_values() → 加载 SG DA
客户端编辑确认
  → edit_sg_confirmation_handler() [mms_s_param.cpp]
    → iec61850s_param_callback()
      → dc_signal_param_set_val(setting_zone)

6. 数据结构

6.1 本地信号存储

类型 容器 数据结构
遥信 g_vec_st vector<stru_local_st_mx> — {base, p_data}
遥测 g_vec_mx vector<stru_local_st_mx> — {base, p_data}
遥控 g_vec_control vector<stru_mms_s_control> — {base, p_data}
定值 g_vec_setting vector<stru_mms_s_setting> — {base, p_data}
参数 g_vec_param vector<stru_mms_s_param> — {base, param_num, p_data[]}

6.2 公共信号基类(myMms_s.h

typedef struct {
    char saddr[MMS_S_STR_LEN];    // 短地址(如 "st.0", "mx.5"
    char desc[MMS_S_STR_LEN];     // 描述
    uint8_t type;                 // 数据类型DATA_TYPE_*
    uint8_t ctrl_model;           // 控制模型
} stru_mms_s_signal_base;

7. 与 libmms_m / libiec61850m 的对比

维度 MMS 客户端 (m) MMS 服务端 (s)
角色 主动连接 IED订阅报告 被动等待客户端连接
模型来源 从 IED 发现 ICD 文件预定义
数据方向 先订阅 RCB再接收报告 收到控制/写请求后更新 DataCenter
线程模型 libmms_m 启动 pthreadlibiec61850m 做桥接 libmms_s 启动 pthreadlibiec61850s 做桥接
桥接层复杂度 复杂RCB 发现/匹配/订阅/GI 触发/重连 相对简单:注册信号+回调libmms_s 处理细节
配置方式 mms_m.xmlIED 连接参数) mms_s.xml信号映射+ PCS.icd模型定义

8. 对外接口

函数 说明
app_iec61850s_init1(void *arg) 第一段初始化:解析 XML、注册值更新回调
app_iec61850s_init2(void *arg) 第二段初始化:初始化信号、启动 MMS 服务器
app_iec61850s(void *arg) 主线程循环
parse_mms_xml(path) 解析 mms_s.xml 配置
mms_cfg_ptr_get() 获取配置数据指针
show_mms_xml(cfg) 打印配置内容(调试)