# libiec61850_MMS服务端API开发手册 **日期**: 2026-06-12 **基于源码**: `src/system/libiec61850s/`, `src/protocol/libmms_s/inc/` --- ## 1. 模块层次 ``` ┌─────────────────────────────┐ │ iec61850s (系统层) │ ← 本文档描述 │ - XML配置解析、信号注册 │ │ - 回调桥接到 datacenter │ ├─────────────────────────────┤ │ libmms_s (协议层) │ ← 底层 API,详见《libmms_s模块分析》 │ - ICD解析、模型创建、IedServer│ │ - 控制/定值/文件服务 │ └─────────────────────────────┘ ``` --- ## 2. 核心概念 ### 2.1 sAddr(信号地址) sAddr 是 IEC 61850 标准中的短地址字段,在 ICD 文件中定义。RTU 用它作为 datacenter 中信号的唯一标识,打通 "MMS 数据属性 ↔ datacenter 信号" 的映射。 ### 2.2 信号类型 | 分类 | ICD FC | datacenter 表 | 说明 | |------|--------|-------------|------| | ST(状态) | ST | signal_out | 遥信/双点状态 | | MX(测量) | MX | signal_out | 遥测/测量值 | | CO(控制) | CO | signal_yk | 遥控输出 | | AO(模拟输出) | 自定义 | signal_ao | 定值区号/SP定值 | | Param(参数) | SG/SE | signal_param | 定值组参数(多区) | --- ## 3. 配置文件格式(mms_s.xml) ```xml ``` - `no`: 序号 - `link`: sAddr,对应 datacenter 中的信号地址和 ICD 中的 sAddr 字段 配置解析后存入 `stru_mms_cfg`,包含 `vec_st`, `vec_mx`, `vec_co`, `vec_ao`, `vec_param` 五个向量。 --- ## 4. 初始化流程 ### 4.1 两阶段初始化 ``` app_iec61850s_init1: 1. 获取进程目录(通过 /proc/self/exe) 2. 解析 config/MMS/mms_s.xml → stru_mms_cfg(信号点表) 3. 设置调试开关: mms_s_dbg_switch(false) 4. 设置文件路径: mms_s_file_path_set(base_path) 5. 注册值更新回调: mms_s_value_update_register(&cb) app_iec61850s_init2: 1. iec61850s_signals_init: - iec61850s_st_signals_init: dc_signal_out_link_with_callback → 获取 ST 信号指针并注册变更回调 回调: iec61850s_st_mx_change_callback → mms_s_value_update → 更新 MMS 模型值 - iec61850s_mx_signals_init: 同上(MX 信号) - iec61850s_control_signals_init: dc_get_yk_signal_info → 获取控制信号信息 mms_s_control_register → 向 libmms_s 注册控制回调 回调: iec61850s_control_callback → dc_signal_yk_set_status - iec61850s_setting_signals_init: dc_signal_ao_link_with_callback → 绑定 AO 信号 mms_s_setting_register → 注册 SP 定值回调 回调: iec61850s_setting_callback → dc_signal_ao_set_val - iec61850s_param_signals_init: dc_get_param_signal_info → 获取 Param 信号指针 mms_s_param_register → 注册定值组回调 回调: iec61850s_param_callback → dc_signal_param_set_val 2. 解析 ICD 文件: config/MMS/PCS.icd 3. 调用 mms_s_init(icd_path, 102) 启动 MMS 服务器 4. 绑定定值区信号: mms_s_bind_param_zone_signal(zone_saddr, iec61850s_sg_change_callback) ``` ### 4.2 信号初始化详细流程 **ST/MX 信号**(单向:datacenter → MMS): ``` datacenter 信号值变化 → iec61850s_st_mx_change_callback(saddr, type, p_data, p_last_data) → dc_get_signal_val(p_data, type) → 字符串值 → mms_s_value_update(saddr, val) → 更新 MMS 模型 → 触发 RCB 报告 ``` **控制信号**(双向:MMS 客户端 → datacenter): ``` 远方 MMS 客户端发送控制命令 → libmms_s control_handler → iec61850s_control_callback(control, state) → 判断 ctrl_model: DIRECT: dc_signal_yk_set_status(DIRECT) SBO: dc_signal_yk_set_status(SELECT) + dc_signal_yk_set_status(DIRECT) STATUS_ONLY: 仅记录日志 ``` **AO/SP 定值信号**(双向:MMS → datacenter): ``` 远方客户端修改 SP 定值 → libmms_s setting writeAccessHandler → iec61850s_setting_callback(setting, data) → dc_set_signal_val_from_str → 解析字符串 → dc_signal_ao_set_val(SELECT+DIRECT or DIRECT only) ``` **Param 定值组信号**(双向,支持多区): ``` 远方客户端 ConfirmEditSG → libmms_s confirmEditSG_callback → iec61850s_param_callback(param, data, zone) → dc_signal_param_set_val(zone, data) ``` --- ## 5. 核心 API ### 5.1 信号注册(iec61850s 内部) ```cpp int iec61850s_signals_init(); ``` **功能**: 从 XML 配置初始化全部五类信号,注册各类回调到 libmms_s。在 `app_iec61850s_init2` 中调用。 ### 5.2 值更新(libmms_s 提供) ```cpp void mms_s_value_update_register(mms_s_value_update_cb *pp_cb); int mms_s_value_update(const char *saddr, const char *value_str); ``` **功能**: 更新 MMS 模型中指定 sAddr 的 DA 值,自动更新时标和品质。 ### 5.3 控制注册(libmms_s 提供) ```cpp int mms_s_control_register(stru_mms_s_control *p_control, int count, mms_s_control_cb p_callback); ``` **功能**: 注册控制 DO 的回调处理函数。 `stru_mms_s_control`: ```c typedef struct { stru_mms_s_signal_base base; // saddr, desc, type, ctrl_model void *p_data; // 信号数据指针(指向 datacenter) }stru_mms_s_control; ``` ### 5.4 SP 定值注册(libmms_s 提供) ```cpp int mms_s_setting_register(stru_mms_s_setting *p_setting, int count, mms_s_setting_cb p_callback); ``` **功能**: 注册 SP(fc=SP)定值的写入回调。 ### 5.5 定值组注册(libmms_s 提供) ```cpp int mms_s_param_register(stru_mms_s_param *p_param, int count, mms_s_param_cb p_callback); ``` **功能**: 注册定值组参数(SG/SE)的确认回调。 `stru_mms_s_param`: ```c typedef struct { stru_mms_s_signal_base base; // saddr, desc, type, ctrl_model void *p_data[MAX_ZONE]; // 各定值区的数据指针 uint8_t param_num; // 定值区数量 }stru_mms_s_param; ``` ### 5.6 其他 libmms_s API ```cpp int mms_s_init(const char *icd_path, int stack_size); // 启动 MMS 服务器 void mms_s_dbg_switch(bool on); // 调试开关 void mms_s_file_path_set(const char *base_path); // 文件路径 int mms_s_bind_param_zone_signal(const char *zone_saddr, mms_s_sg_change_cb cb); // 绑定定值区 struct _sIedModel_wrapper *mms_s_get_icd_ptr(); // 获取 IedModel IedServer mms_s_get_ied_server_ptr(); // 获取 IedServer ``` --- ## 6. 运行时流程 ### 6.1 主线程循环 ```cpp void *app_iec61850s(void *arg): while(1): task_event_recv(p_event, EV_TIMER1 | EV_TIMER2 | EV_TIMER3, ...) EV_TIMER1 (10ms): 空闲 EV_TIMER2 (100ms): 空闲 EV_TIMER3 (1000ms): - check_sg_zone_change(): 检测定值区号变化,更新 MMS 模型 - p_app->run_cnt++: 运行计数 ``` ### 6.2 定值区切换检测 ``` ie61850s_sg_change_callback(zone_saddr, new_act_sg): → 遍历 g_vec_setting 找到匹配的 saddr → dc_signal_ao_set_val(SELECT + DIRECT) 通过 datacenter 更新值 → 设置 g_sg_zone_saddr 和 g_sg_zone_act_sg check_sg_zone_change() (EV_TIMER3 中): → 如果有待更新信号 → mms_s_value_update(saddr, val) → 更新 MMS 模型,通知所有订阅客户端 ``` --- ## 7. 常见配置场景 ### 7.1 添加新的遥测信号 1. 在 ICD 中定义 DA 的 sAddr 2. 在 `mms_s.xml` 的 `` 中添加 `` 3. 在 datacenter 初始化中注册该信号 4. 重启 RTU,初始化时自动绑定 ### 7.2 添加新的遥控信号 1. ICD 中定义含 `ctlModel` 的 CO DO 2. `mms_s.xml` 的 `` 中添加信号 3. datacenter 中注册 yk 信号 4. `iec61850s_control_signals_init` 自动通过 sAddr 找到对应的 ModelNode 安装控制回调 ### 7.3 配置多定值区参数 1. ICD 中 SG 定义多组 SE 2. `mms_s.xml` 的 `` 中添加信号 3. datacenter 中注册 param 信号(`dc_signal_param_reg` 需指定定值区数) 4. `iec61850s_param_signals_init` 自动获取各定值区数据指针