# libiec61850_MMS客户端API开发手册 **日期**: 2026-06-12 **基于源码**: `release/inc/myMms_m.h`, `src/system/libiec61850m/` --- ## 1. 模块层次 RTU 的 MMS 客户端分为两层: ``` ┌─────────────────────────────┐ │ iec61850m (系统层) │ ← 本文档描述 │ - 配置解析、信号初始化 │ │ - 回调转发给 datacenter │ ├─────────────────────────────┤ │ libmms_m (协议层) │ ← 底层 API,详见《libmms_m模块分析》 │ - IED 连接、定时器、事件 │ │ - MMS 协议编解码 │ └─────────────────────────────┘ ``` `iec61850m` 负责解析 XML 配置(`mms_m.xml`),编排信号初始化流程,将 `libmms_m` 的数据通过回调桥接到数据中心(`datacenter`)。 --- ## 2. 核心 API(`release/inc/myMms_m.h`) ### 2.1 `mms_m_out_init` ```c int mms_m_out_init(stru_cfg *p_cfg, int debug_print_flag, uint32_t connectionTimeout); ``` **功能**: 创建一个 IED 连接。 | 参数 | 说明 | |------|------| | `p_cfg` | 配置文件结构体指针,必须包含 `path`(配置文件路径) | | `debug_print_flag` | 调试打印开关(1=开, 0=关),开启后打印 ICD 发现详情和 MMS 值 | | `connectionTimeout` | 连接超时(毫秒) | **返回值**: 成功返回 `obj_fd`(>0),失败返回 `-1`。 **副作用**: 创建 `stru_mms_m_obj` 实例,启动独立工作线程 `mms_m_run_thread`,开始异步连接远方 IED。 --- ### 2.2 `mms_m_out_get_connect_status` ```c int mms_m_out_get_connect_status(int app_fd, mms_m_out_status_cb p_func); ``` **功能**: 注册连接状态回调。 | 参数 | 说明 | |------|------| | `app_fd` | `mms_m_out_init` 返回的句柄 | | `p_func` | 回调函数 `void(int fd, int status)`,status: `MMS_M_ON_LINE` 或 `MMS_M_OFF_LINE` | --- ### 2.3 `mms_m_out_debug_print_swicth` ```c int mms_m_out_debug_print_swicth(int app_fd, int debug_print_flag); ``` **功能**: 运行时开关调试打印。 --- ### 2.4 `mms_m_out_do_set_yk` ```c int mms_m_out_do_set_yk(stru_mms_m_event *p_event); ``` **功能**: 下达遥控命令(Select/Direct/Cancel)。 ```c typedef struct { int app_fd; // IED 句柄 char ied[64]; // IED 名称(app_fd = 0 时按名称匹配) char saddr[256]; // 信号地址 uint8_t ctrl_type; // 操作类型 char data[128]; // 操作数据 int set_fd; // 操作序号 }stru_mms_m_event; ``` `ctrl_type` 取值: - `_MMS_M_EVENT_CO_SELECT`: 选择(SBO 模式第一步) - `_MMS_M_EVENT_CO_DIRECT`: 执行(Direct 或 SBO 第二步) - `_MMS_M_EVENT_CO_CANCEL`: 取消 **注意**: `app_fd > 0` 时按句柄查找;`app_fd = 0` 时按 `ied` 名称查找。 --- ### 2.5 `mms_m_out_read_ao_or_params` ```c int mms_m_out_read_ao_or_params(int app_fd, uint8_t type, const char *saddr); ``` **功能**: 读取 AO 或 Param 值。 | 参数 | 说明 | |------|------| | `type` | `_MMS_M_EVENT_AO_READ` 或 `_MMS_M_EVENT_PARAM_READ` | | `saddr` | 指定信号地址(`nullptr` 时读取全部) | --- ### 2.6 `mms_m_out_get_value` ```c int mms_m_out_get_value(int fd, mms_m_out_value_cb p_func); ``` **功能**: 注册数据推送回调。所有读取到的 ST/MX/AO/Param 值都通过此回调向外推送。 ```c typedef void (*mms_m_out_value_cb)(stru_mms_m_out_value &val); ``` `stru_mms_m_out_value` 字段: ```c typedef struct { int app_fd; // IED 句柄 char name[256]; // 信号 saddr char desc[256]; // 信号描述 char reference[256]; // MMS 对象引用 void *p_value; // 数据指针 uint8_t type; // MMS 数据类型(BOOLEAN/INTEGER/UNSIGNED/FLOAT/STRING) int quality; // 品质位 stru_mms_m_time time; // 时标 int reason; // 原因码(ALL_CALL/GI/dchg/qchg 等) }stru_mms_m_out_value; ``` --- ### 2.7 `mms_m_out_bind_param_zone_signal` ```c int mms_m_out_bind_param_zone_signal(int app_fd, const char *zone_saddr); ``` **功能**: 绑定定值区号信号。定值区号变化时自动触发参数重读。 --- ### 2.8 `mms_m_out_set_rcb_numbers` ```c int mms_m_out_set_rcb_numbers(int app_fd, const char *rcb_numbers); ``` **功能**: 设置 RCB 订阅编号。 | 输入 | 行为 | |------|------| | 不调用 | 默认订阅 `"01"` | | `"01"` | 只订阅 01 号 | | `"01,02,03"` | 订阅多个编号 | | `"*"` | 订阅全部 RCB | | `"abc"` / `"1"` / `"012"` | 非法,返回 -1 | --- ### 2.9 工具函数 ```c void *mms_m_create_data_ptr(uint8_t type); // 创建数据指针(需手动 delete) int mms_m_set_data_value(void *srt, void *dst, uint8_t type); // 类型化赋值 int mms_m_get_data_value_str(void *data, uint8_t type, char *s); // 转字符串 int mms_m_set_data_by_str(void *data, uint8_t type, const char *s); // 从字符串设置 char *mms_m_out_reason_str(int reason); // 原因码→字符串 ``` `type` 取值: `MMS_BOOLEAN`, `MMS_INTEGER`, `MMS_UNSIGNED`, `MMS_FLOAT`, `MMS_STRING` --- ## 3. iec61850m 初始化流程 ### 3.1 两阶段初始化 ``` app_iec61850m_init1: 1. 获取进程目录 2. 解析 config/MMS/mms_m.xml(点表配置) - St/Mx/Co/Ao/Param 各信号点的 saddr/type/ctrl_model/desc 3. 为每个 IED 调用 mms_m_out_init → 获取 obj_fd 4. 注册数据回调: mms_m_out_get_value → 桥接到 datacenter 5. 注册连接状态回调 app_iec61850m_init2: 1. 调用 mms_m_out_debug_print_swicth(传入调试标志) 2. 调用 mms_m_out_set_rcb_numbers(传入 RCB 编号配置) 3. 调用 mms_m_out_bind_param_zone_signal(绑定定值区信号) ``` ### 3.2 数据回调桥接 iec61850m 的数据回调完成 MMS 值 → datacenter 的转换: ``` mms_m_out_get_value_callback(out_val): → 根据 reason 分类处理: ALL_CALL: dc_set_out_signal_val(name, p_value, type, quality) GI: dc_set_out_signal_val(name, p_value, type, quality) dchg/qchg: // 报告触发,同上 → 对 CO/AO/Param: 转发到对应的 datacenter 写接口 ``` --- ## 4. 配置文件格式(mms_m.xml) ```xml ``` - `link`: 信号 saddr,对应 datacenter 中的信号地址 - `reference`: IEC 61850 对象引用,用于 `IedConnection_readObject` - `name`: IED 名称,用于连接日志 - `rcb_numbers`: RCB 编号过滤(逗号分隔,可选) --- ## 5. 常见使用场景 ### 5.1 读取遥测/遥信 ``` // 自动完成 — 定时器 T0 (120s) 触发 All-Call,T1 (60s) 触发 GI // 数据通过 mms_m_out_get_value 注册的回调推送 // 用户只需在 iec61850m_init1 中调用 mms_m_out_get_value 注册回调 ``` ### 5.2 手动读取 AO 值 ```cpp // 读取指定 AO mms_m_out_read_ao_or_params(fd, _MMS_M_EVENT_AO_READ, "AO_Signal_1"); // 读取全部 AO mms_m_out_read_ao_or_params(fd, _MMS_M_EVENT_AO_READ, nullptr); ``` ### 5.3 下达遥控命令 ```cpp // SBO 模式 stru_mms_m_event event = {}; event.app_fd = fd; event.ctrl_type = _MMS_M_EVENT_CO_SELECT; strncpy(event.saddr, "YK_Signal_1", sizeof(event.saddr)); mms_m_out_do_set_yk(&event); // 确认后执行 event.ctrl_type = _MMS_M_EVENT_CO_DIRECT; mms_m_out_do_set_yk(&event); ``` ### 5.4 写入定值 ```cpp // 定值写入通过 mms_m_out_read_ao_or_params 触发 O→Param 流程 // libmms_m 内部自动处理 SG/SE 编辑-确认流程 ``` ### 5.5 RCB 编号配置 ```cpp // 只订阅 01 号 RCB mms_m_out_set_rcb_numbers(fd, "01"); // 订阅 01, 02, 03 号 mms_m_out_set_rcb_numbers(fd, "01,02,03"); // 订阅全部 mms_m_out_set_rcb_numbers(fd, "*"); ```