RTU/mimo/工程/libiec61850_MMS服务端API开发手册.md

267 lines
8.5 KiB
Markdown
Raw Permalink 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
**基于源码**: `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
<mms_s>
<St>
<Signal no="1" link="ST_Signal_1" />
<Signal no="2" link="ST_Signal_2" />
</St>
<Mx>
<Signal no="1" link="MX_Signal_1" />
</Mx>
<Co>
<Signal no="1" link="YK_Signal_1" />
</Co>
<Ao>
<Signal no="1" link="SG_Signal_1" />
</Ao>
<Param>
<Signal no="1" link="Param_Signal_1" />
</Param>
</mms_s>
```
- `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);
```
**功能**: 注册 SPfc=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``<Mx>` 中添加 `<Signal link="新sAddr" />`
3. 在 datacenter 初始化中注册该信号
4. 重启 RTU初始化时自动绑定
### 7.2 添加新的遥控信号
1. ICD 中定义含 `ctlModel` 的 CO DO
2. `mms_s.xml``<Co>` 中添加信号
3. datacenter 中注册 yk 信号
4. `iec61850s_control_signals_init` 自动通过 sAddr 找到对应的 ModelNode 安装控制回调
### 7.3 配置多定值区参数
1. ICD 中 SG 定义多组 SE
2. `mms_s.xml``<Param>` 中添加信号
3. datacenter 中注册 param 信号(`dc_signal_param_reg` 需指定定值区数)
4. `iec61850s_param_signals_init` 自动获取各定值区数据指针