206 lines
8.1 KiB
Markdown
206 lines
8.1 KiB
Markdown
# DCU_HOST 项目 lib60870 CBB 库调用参考
|
||
|
||
> **用途**: RTU 项目开发 IEC 101/104 时的参考工程
|
||
> **源项目**: [DCU_HOST](../../../../DCU_HOST/) (科大智能 DCU 通信板)
|
||
> **原理由**: DCU_HOST 已成熟使用 lib60870 CBB 库实现 101/104 从站,调用模式可直接参考
|
||
|
||
---
|
||
|
||
## 1. DCU_HOST 项目背景
|
||
|
||
DCU_HOST 是基于 **RT-Thread** 实时操作系统的嵌入式通信板项目,运行在 STM32H743 平台。其 `applications/iec_prtcl/` 模块是对 lib60870 CBB 规约库的完整封装。
|
||
|
||
### 1.1 模块文件结构
|
||
|
||
```
|
||
DCU_HOST/applications/
|
||
├── iec_prtcl/ # ★ IEC 规约应用层
|
||
│ ├── Iec_Use.h # CS10x 实体封装 + 外部接口声明
|
||
│ ├── Iec_Use.c # ★ 主循环驱动 (IecEntry) + 收/发/调度
|
||
│ ├── Protocol_Config.h # 参数配置接口声明
|
||
│ └── Protocol_Config.c # ★ 参数配置 + 回调注册 (SetProtocolItfc)
|
||
├── data/iec_itfc/ # ★ 数据回调层 (规约 ↔ 业务数据)
|
||
│ ├── YcItfc.c/h # 遥测回调 (GetYcCountByGroup / GetYcValueByGroup)
|
||
│ ├── YxItfc.c/h # 遥信回调 + SOE 回调
|
||
│ ├── YkItfc.c/h # 遥控回调 (SetYkInfor / YkResultNofify)
|
||
│ ├── GbParamItfs.c/h # ★ 参数/定值读写回调 (882行)
|
||
│ ├── DdItfc.c/h # 电度回调
|
||
│ ├── FaultItfc.c/h # 故障事件回调
|
||
│ └── FileParamItfs.c/h # 文件服务回调
|
||
└── cbblibs/lib60870/ # lib60870 CBB 库 (git submodule)
|
||
```
|
||
|
||
### 1.2 lib60870 CBB 库版本
|
||
|
||
与 RTU 项目使用**同一套** CBB 库(同为科大智能 IECVer2.01.059_260202),API 完全一致。
|
||
|
||
---
|
||
|
||
## 2. 核心架构:实体池 + 线程驱动
|
||
|
||
### 2.1 实体封装 `stLIB60870ENTITY`
|
||
|
||
DCU_HOST 将 `CS10x` 封装了一层:
|
||
|
||
```c
|
||
#define MAX_CS10X_NUM 2 // 最大支持 2 个 CS10x 实例 (如一路104 + 一路101)
|
||
|
||
typedef struct {
|
||
u8 ucBusy; // 是否使用中
|
||
u8 ucType; // PRTCL_104_S / PRTCL_101_S
|
||
u32 uiItfs; // 绑定的通信接口编号 (如 ETH0=0x0A000001)
|
||
u32 uiTime; // 链路空闲超时累计 (ms)
|
||
stLIB60870BUFF stBuf; // 内部收发缓冲区
|
||
CS10x stCs10x; // ★ CBB 库的 CS10x 结构体 (值语义)
|
||
} stLIB60870ENTITY;
|
||
|
||
// 全局实体池
|
||
stLIB60870ENTITY g_astLib60870Entity[MAX_CS10X_NUM];
|
||
```
|
||
|
||
### 2.2 线程入口 `IecEntry()`
|
||
|
||
```c
|
||
void IecEntry(void *pvArg) {
|
||
// 1. 创建 10ms 周期定时器
|
||
rt_timer_create("IEC_tm1", TmExpire, ..., 10, RT_TIMER_FLAG_PERIODIC);
|
||
|
||
// 2. 初始化环形缓冲区 (用于跨线程数据传递)
|
||
IecRingblkInit();
|
||
|
||
// 3. 主循环
|
||
while(1) {
|
||
rt_event_recv(..., &uiEvent); // 等待事件
|
||
|
||
if(uiEvent & EV_TIMER1_IEC) {
|
||
Schedule60870(10); // ★ 10ms 驱动一次
|
||
}
|
||
if(uiEvent & EV_PARA_UPDATE) {
|
||
UpdateParamLib60870(...); // 参数热更新
|
||
}
|
||
rb_channel_process(&g_stIecChannel); // 处理收到的数据
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.3 数据接收链路
|
||
|
||
```
|
||
串口/网口收数据
|
||
→ CommChannel_SendData / 加密解密
|
||
→ IecRingblkInput(pucData, usLen, uiItfs) // 写入环形缓冲
|
||
→ rb_channel_process() // 主循环中消费
|
||
→ RecvDateProtocolItfs()
|
||
→ DataProc60870()
|
||
├── GetEntity60870(ucType, uiItfs) // 获取/创建实体
|
||
│ ├── pstEntity->ucBusy = 1
|
||
│ ├── memset(&stCs10x, 0, sizeof(CS10x))
|
||
│ ├── 绑定缓冲区指针
|
||
│ ├── ProtocolEntityConfig() → CS10x_104Init / CS10x_101Init
|
||
│ └── Cs10xConfig() → 参数配置 + 回调注册
|
||
└── CS10x_DoRecv(&pstEntity->stCs10x, pucData, usLen) // ★ 喂给规约栈
|
||
```
|
||
|
||
### 2.4 发送回调
|
||
|
||
```c
|
||
s32 DataSend60870(u8 *pucBuf, u16 usLen, void* pvArg) {
|
||
u32 uiItfs = *(u32*)pvArg; // pvArg = &pstEntity->uiItfs
|
||
return CommChannel_SendData(pucBuf, usLen, uiItfs);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 初始化流程
|
||
|
||
### 3.1 104 从站初始化
|
||
|
||
```c
|
||
// 1. 选择协议类型
|
||
enType = CS104_TYPE_S; // 或 CS101_TYPE_S
|
||
|
||
// 2. 初始化规约栈
|
||
CS10x_104Init(pCs10x, DataSend60870, &pstEntity->uiItfs, enType);
|
||
|
||
// 3. 配置参数 (通过参数映射表)
|
||
Cs10xConfig(pstEntity, &g_stParamMappingTable);
|
||
// → SetProtocol104Param()
|
||
// ├── CS10x_SetAppParameters(&stAppParam)
|
||
// ├── CS10x_SetAPCIParameters(&stApciParam)
|
||
// ├── CS10x_SetYcType(浮点/整形)
|
||
// ├── CS10x_SetYxType(单点/双点)
|
||
// ├── CS10x_SetDdType / CS10x_FrameGap / CS10x_SetMultFrameEn
|
||
// ├── CS10x_FaultEventEn / CS10x_SetSendSoe / CS10x_SetSendCos
|
||
// ├── CS10x_SetYKEendFrame / CS10x_SetReadFileVSQ
|
||
// └── CS10x_SetPresetContType
|
||
// → SetProtocolItfc() ← ★ 所有回调在此注册
|
||
```
|
||
|
||
### 3.2 101 从站初始化 (差异项)
|
||
|
||
101 额外配置:
|
||
- `CS10x_SetAppParameters`: 需要 `iSzOfLinkAddr` + `iLinkAddr`
|
||
- `CS10x_ResendGap` / `CS10x_ResendCnt`: 重发参数
|
||
- `CS10x_SetHeartTimeGap`: 心跳间隔
|
||
- `CS10x_SetFileAckType`: 文件确认
|
||
- `CS10x_SetInitType`: 简单初始化
|
||
|
||
---
|
||
|
||
## 4. 回调注册全景 (SetProtocolItfc)
|
||
|
||
```c
|
||
void SetProtocolItfc(stLIB60870ENTITY *pstEntity, u8 ucType) {
|
||
CS10x *pstCs10x = &pstEntity->stCs10x;
|
||
|
||
// ── 对所有类型 (主站/从站) ──
|
||
CS10x_TimeRWHandler(pstCs10x, GetTimeItfs, SetTimeItfs);
|
||
CS10x_WR_ResetHandler(pstCs10x, Cs10xReadFileResetCOI, Cs10xWriteFileResetCOI);
|
||
CS10x_SetYkInforHandler(pstCs10x, SetYkInfor);
|
||
|
||
// ── 仅从站 ──
|
||
if (PRTCL_104_S == ucType || PRTCL_101_S == ucType) {
|
||
// 遥测
|
||
CS10x_S_GetYcByGroupHandler(pstCs10x, GetYcCountByGroup, GetYcValueByGroup);
|
||
// 扰动遥测
|
||
CS10x_S_DiturbYcHandler(pstCs10x, GetDiturbYc, GetDiturbYcSendNum, UpdateDiturbYcPtrOut);
|
||
// 遥信
|
||
CS10x_S_GetYxByGroupHandler(pstCs10x, GetYxCountByGroup, GetYxStatusByGroup);
|
||
// SOE
|
||
CS10x_S_SOEHandler(pstCs10x, GetSOE, GetSOESendNum, UpdateSoePtrOut);
|
||
// 电度
|
||
CS10x_S_GetDdByGroupHandler(pstCs10x, GetDdCountByGroup, GetDdValueByGroup);
|
||
// 时标电度
|
||
CS10x_S_DiturbDduHandler(pstCs10x, GetTimeDdu, GetTimeDduSendNum, UpdateTimeDduPtrOut);
|
||
// 故障事件
|
||
CS10x_S_FaultEventHandler(pstCs10x, GetEventSendNum, GetFaultEvent, UpdateFaultEventPtrOut);
|
||
// 遥控校验
|
||
CS10x_S_YkVerifyHandler(pstCs10x, Cs10xYkVerifyItfs);
|
||
// 定值区
|
||
CS10x_S_ParamAreaHandler(pstCs10x, GbParamGetParamArea, GbParamSetParamArea);
|
||
// 参数读写
|
||
CS10x_S_IECParamHandler(pstCs10x, GbParamAddElement, GbParamRunRding, GbParamRunWting);
|
||
// 参数信息
|
||
CS10x_S_GetParamInfoHandler(pstCs10x, GbParamGetTotalNum, GbParamGetIecParam);
|
||
// 文件服务
|
||
CS10x_S_FileReadOprtHandler(pstCs10x, Fm_GetDirFile, Fm_SearchDirFileNum, Fm_ReadFile, ...);
|
||
CS10x_S_FileWriteOprtHandler(pstCs10x, Cs10xWriteItfs, Cs10xWriteFileCheckItfs, Cs10xWriteFinishItfs, ...);
|
||
// 升级
|
||
CS10x_S_UpdateProcHandler(pstCs10x, NULL);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 子文档索引
|
||
|
||
| 子文档 | 内容 | 对应回调 |
|
||
|--------|------|----------|
|
||
| [01-总召与遥测遥信](01-总召与遥测遥信.md) | GetYcCountByGroup / GetYcValueByGroup / GetYxCountByGroup / GetYxStatusByGroup 详细实现 | `CS10x_S_GetYcByGroupHandler` / `CS10x_S_GetYxByGroupHandler` |
|
||
| [02-SOE与扰动数据](02-SOE与扰动数据.md) | GetSOE / GetSOESendNum / UpdateSoePtrOut + 扰动遥测回调 | `CS10x_S_SOEHandler` / `CS10x_S_DiturbYcHandler` |
|
||
| [03-遥控与对时](03-遥控与对时.md) | SetYkInfor / YkResultNofify / Cs10xYkVerifyItfs / GetTimeItfs / SetTimeItfs | `CS10x_S_YkVerifyHandler` / `CS10x_TimeRWHandler` |
|
||
| [04-参数定值与文件服务](04-参数定值与文件服务.md) | GbParamGetParamArea / GbParamAddElement / 文件读写 | `CS10x_S_ParamAreaHandler` / `CS10x_S_IECParamHandler` / 文件回调 |
|
||
| [05-故障事件与电度](05-故障事件与电度.md) | GetFaultEvent / GetDdValueByGroup | `CS10x_S_FaultEventHandler` / `CS10x_S_GetDdByGroupHandler` |
|