RTU/mimo/工程/libiec61850_MMS客户端API开发手册.md

305 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
<IED name="PCS9700" ip="192.168.1.100" port="102" rcb_numbers="01,02">
<St>
<Signal no="1" link="ST_Signal_1" reference="PCS9700CTRL/GGIO1$ST$Ind1$stVal" /> <!-- (1) -->
</St>
<Mx>
<Signal no="1" link="MX_Signal_1" reference="PCS9700MEAS/MMXU1$MX$PhV$phsA$cVal$mag$f" />
</Mx>
<Co>
<Signal no="1" link="YK_Signal_1" reference="PCS9700CTRL/CSWI1$CO$Pos$Oper$ctlVal" />
</Co>
<Ao>
<Signal no="1" link="SG_Signal_1" reference="PCS9700PROT/LLN0$SG$sg1$StrVal" />
</Ao>
<Param>
<Signal no="1" link="Param_Signal_1" reference="PCS9700PROT/PTOC1$SG$sg1$StrVal" />
</Param>
</IED>
```
- `link`: 信号 saddr对应 datacenter 中的信号地址
- `reference`: IEC 61850 对象引用,用于 `IedConnection_readObject`
- `name`: IED 名称,用于连接日志
- `rcb_numbers`: RCB 编号过滤(逗号分隔,可选)
---
## 5. 常见使用场景
### 5.1 读取遥测/遥信
```
// 自动完成 — 定时器 T0 (120s) 触发 All-CallT1 (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, "*");
```