RTU/mimo/工程/DCU_HOST
ypc cb60d687e3 feat: channel_config 统一重构 + lib60870 CBB 库集成 + libiec 文件拆分
## channel_config 通道配置统一重构
- 合并 channel_config.xml / channel_config_rk.xml 为单文件
- Channel 新增 bind 字段显式绑定私有规约(channel_cfg_find_by_bind)
- 转发隧道改为 from_saddr→to_saddr 单向,支持 ICP67维护+IEC101/104
- com_channel_recv_cb 重构为三级路由: 转发→bind→IEC
- 去除 ICP66→ICP67 帧转换逻辑(decode_frame_codec 清空)
- com_recv_data 去除硬编码 uart0, 简化为纯 IEC 头检测
- com_scan_send_data_to_app 增加 p_event 空指针防护
- self_ptl_init 改用 bind 字段绑定 UART+通过转发规则反查 TCP
- self_ptl 内部转发加 TCP 连接状态守卫, p_event 未就绪时仅入队
- 新增参数缺省值重构相关文件

## lib60870 CBB 库集成
- 替换原 lib60870 为科大智能 CBB 库
- 新增 cbb_compat.h 兼容层, 通过 gcc -include 注入类型定义
- 新增 CBB 库完整文档(lib60870_mkdocs)

## libiec 文件拆分
- iec_method.cpp 拆分为 iec_common/iec_dd/iec_fault/iec_file/
  iec_param/iec_soe/iec_time/iec_yc/iec_yk/iec_yx 等独立文件

## 工程文档
- 新增 15+ 模块分析/plan/中间文档
2026-07-01 14:52:22 +08:00
..
01-总召与遥测遥信.md feat: channel_config 统一重构 + lib60870 CBB 库集成 + libiec 文件拆分 2026-07-01 14:52:22 +08:00
02-SOE与扰动数据.md feat: channel_config 统一重构 + lib60870 CBB 库集成 + libiec 文件拆分 2026-07-01 14:52:22 +08:00
03-遥控与对时.md feat: channel_config 统一重构 + lib60870 CBB 库集成 + libiec 文件拆分 2026-07-01 14:52:22 +08:00
04-参数定值与文件服务.md feat: channel_config 统一重构 + lib60870 CBB 库集成 + libiec 文件拆分 2026-07-01 14:52:22 +08:00
05-故障事件与电度.md feat: channel_config 统一重构 + lib60870 CBB 库集成 + libiec 文件拆分 2026-07-01 14:52:22 +08:00
README.md feat: channel_config 统一重构 + lib60870 CBB 库集成 + libiec 文件拆分 2026-07-01 14:52:22 +08:00

README.md

DCU_HOST 项目 lib60870 CBB 库调用参考

用途: RTU 项目开发 IEC 101/104 时的参考工程 源项目: 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_260202API 完全一致。


2. 核心架构:实体池 + 线程驱动

2.1 实体封装 stLIB60870ENTITY

DCU_HOST 将 CS10x 封装了一层:

#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()

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 发送回调

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 从站初始化

// 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)

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-总召与遥测遥信 GetYcCountByGroup / GetYcValueByGroup / GetYxCountByGroup / GetYxStatusByGroup 详细实现 CS10x_S_GetYcByGroupHandler / CS10x_S_GetYxByGroupHandler
02-SOE与扰动数据 GetSOE / GetSOESendNum / UpdateSoePtrOut + 扰动遥测回调 CS10x_S_SOEHandler / CS10x_S_DiturbYcHandler
03-遥控与对时 SetYkInfor / YkResultNofify / Cs10xYkVerifyItfs / GetTimeItfs / SetTimeItfs CS10x_S_YkVerifyHandler / CS10x_TimeRWHandler
04-参数定值与文件服务 GbParamGetParamArea / GbParamAddElement / 文件读写 CS10x_S_ParamAreaHandler / CS10x_S_IECParamHandler / 文件回调
05-故障事件与电度 GetFaultEvent / GetDdValueByGroup CS10x_S_FaultEventHandler / CS10x_S_GetDdByGroupHandler