GD32H7 FTU 馈线终端

配电自动化 FTU (Feeder Terminal Unit) — 嵌入式固件源码分析
GD32H7 Cortex-M7 FreeRTOS IEC 61850 GOOSE/MMS lwIP 1.4.1 IAR EWARMv7
📅 分析日期: 2026-07-16 📁 2266 文件 📊 101 MB ⏱ 348K 行代码
← 返回代码分析列表
189
.c 源文件
663
.h 头文件
348K
总代码行
18
FreeRTOS 任务
3
计量方案
3路
以太网
🏗️ 系统架构
保护逻辑
故障诊断
遥控/遥测
FTP 升级
↑ 应用层 ↑
IEC 61850 GOOSE
IEC 61850 MMS
IEC 101/104
MODBUS
↑ 协议栈层 ↑
lwIP TCP/IP
CLNP/OSI
CH395 独立栈
↑ 网络层 ↑
FreeRTOS V8.2.3
OS_vF 适配层
↑ 操作系统 ↑
RN8302B
SPI ×6
ENET0/1
NAND
I2C
↑ 驱动层 ↑
GD32H7 HAL
CMSIS
FATFS / yaffs2
📋 平台规格
SoC
GD32H7xx (GigaDevice)
核心
ARM Cortex-M7 @ 600 MHz
RTOS
FreeRTOS V8.2.3 · 100Hz Tick · 32 优先级
工具链
IAR EWARMv7 (ICCARM)
架构
支持主从双 MCU (USR_APP==0/1)
内存
CCM 64KB + 外部 SDRAM 3MB
网络
3 路: ENET0 + ENET1 + CH395 SPI
计量
RN8302B (主) / ADE9078 / ATT7022
🚀 启动流程
1
Reset_Handler
清零 SRAM → SystemInit (PLL/时钟) → __iar_program_start (C 运行时)
2
main() 初始化
向量表偏移 → NVIC 分组 → MPU → Cache → bsp_Init → FS_init → 读 MAC 地址
3
任务创建
从机模式: AppTaskCreate() 创建所有 FreeRTOS 任务
主机模式: root() → ThreadInit() → iniFileSetup() → SystemInit2() (含 GOOSE/MMS 启动)
4
vTaskStartScheduler()
启动 FreeRTOS 调度器, 多任务开始运行
🧵 FreeRTOS 任务
任务 优先级 描述
BCM2464 KBBCM 协议通信 · 最高优先级 · 最大栈
vTaskLED202 KBLED 闪烁 · 自检 · FTP 任务监控
vTaskAbnormal214 KB以太网异常检测 · 100ms 周期
tClnpGOOSE_PRIO32 KBCLNP/GOOSE 协议栈主任务 · 信号量驱动
TCP/IP≈248 KBlwIP tcpip_thread · mbox_size=100
PUBGOOSE_PRIO8 KBGOOSE 发布 · ASN.1 编码 · CLNP 发送
deamonGooseDEAMON_PRIO8 KBGOOSE 守护 · 链路状态监控
vTaskMain14 KB以太网初始化 · ETH0/1 · FTP 启动
tUsmart108 KBUSMART 串口调试 · Letter_shell
vPrintMsg104 KB消息打印 · 远程 shell 输出
vTaskFusart34 KBFPGA UART 通信
vTaskStart42 KB启动预留 · 当前为空循环
t_shell52 KBLetter_shell 命令行
SpiS1Recv*SPI_PRIOSPI S1 接收处理 (×2)
CH395_ETH2_linkCH395_PRIOCH395 第3路以太网链路管理
tcpShell*TCP_PRIOTCP Shell 远程调试 (发送/接收)
⚠️ BCM 任务栈 64 KB 是其他任务的 16~64 倍, 建议测量实际使用量
📡 协议栈
IEC 61850 GOOSE
SISCO MMS-EASE-Lite + 自研 CLNP 适配层
二层组播 · EtherType 0x88B8 · ASN.1 BER 编解码
关键文件: clnp.c, pub.c, Goose_Smv.c, Goose_Creat.c, iec_rx.c, ASN1.c
IEC 61850 MMS
SISCO MMS-EASE-Lite (vx5mms 移植版)
ACSE 关联控制 · BRCB/URCB 报告 · 控制 · 日志
TCP/IP (RFC 1006) 或 OSI 协议栈
SCL 配置通过 libini/mxml 解析
其他规约
  • IEC 60870-5-101/104
  • MODBUS (多种变种)
  • DL/T 645
  • 私有/地方规约 ×10+
📊 代码规模
IEC 61850 协议栈
170K
保护/应用逻辑
19.5K
User 应用层
32.5K
FreeRTOS 内核
70.8K
GD32H7 HAL
23.6K
协议栈: 128 .c + 229 .h = 170,250 行
保护逻辑: 11 .c + 22 .h = 19,458 行
平台抽象: 13 .c + 8 .h = 5,936 行
计量驱动: RN8302B 2,917 行 (1 .c + 1 .h)
main.c: 4,304 行 (含任务定义 + 启动逻辑)
🔌 驱动与芯片
🔋
RN8302B
三相计量 · SPI · 主方案
主用
🔋
ADE9078
ADI 计量芯片
备用
🔋
ATT7022
钜泉计量芯片
备用
🌐
CH395
SPI 以太网 · 第3路
主用
📁
NAND Flash
yaffs2 + FATFS
主用
🕒
RX8025T
I2C RTC · 实时时钟
主用
🔗 模块依赖
main.c
  • gd32_bsp.h (bsp_Init)
  • netconf.h (LwIP_Init)
  • eth0.h / eth1.h
  • FreeRTOS 头文件
  • ARM9_ftu_net_pro (root, BCM)
  • 所有外设驱动 (bsp/)
  • FATFS / yaffs2
  • Letter_shell
ARM9_ftu_net_pro (协议栈)
  • bsp_spi_rn8302b (硬件 SPI)
  • lwIP 1.4.1 (TCP/IP socket)
  • etherMultiLib (组播)
  • FreeRTOS (OS_vF 适配层)
  • FATFS (文件读写)
  • User/Lib (通用库)
GOOSE (clnp.c → pub.c)
  • ASN1.c (BER 编解码)
  • Goose_Smv.c (数据模型)
  • Goose_Creat.c (PDU 构造)
  • lwIP raw socket
  • OS_vF (信号量/任务)
vx5mms (MMS 栈)
  • glbtypes.h / sysincs.h
  • mvl_defs.h / mvl_log.h
  • uca_obj.h / uca_srvr.h
  • scl.h (SCL 配置)
  • asn1defs.h / acse2.h
🔍 发现的问题与优化建议
⚡ 高风险 → 查看重构方案详情
vTaskDelete(NULL) 调用风险
clnp.c 中 xTaskCreate 失败后调用 vTaskDelete(NULL) 意图删除刚创建失败的任务, 但实际效果是删除当前任务自身, 逻辑矛盾。应直接返回错误。
ARM9_ftu_net_pro/PROTOCOL/netpro/goose/clnp.c:218, 285
OS 适配层性能开销
vxWorks→FreeRTOS 适配层每次调用通过结构体传参 (TASK_PARAS 含 10 个 int), 有额外内存分配开销。建议逐步替换为直接调用 FreeRTOS API。
ARM9_ftu_net_pro/PLATFORM/OS_vF.c
⚡ 中等风险
lwIP 校验和由软件计算
未启用硬件校验和控制。GD32H7 ENET 外设支持硬件加速, 启用后可降低 CPU 负载 5~15% (网络密集场景)。
User/ETH/lwipopts.h:227
GOOSE 发布采用忙等信号量
pubTask 在信号量等待后通过循环轮询标志位, FD_Num 较大时空转浪费 CPU。建议使用事件组或队列精确触发。
ARM9_ftu_net_pro/.../pub.c:72
字符串缓冲区溢出风险
readMACaddr() 中 MAC 地址解析未做边界检查, 入参格式异常时可能越界。
User/main.c:613-717
printf 可能在中断上下文调用
ENET_IRQHandler 等中断中调用了 printf, 而 printf 可能依赖 FreeRTOS 信号量/队列, 存在死锁风险。
多个文件
lwIP 版本陈旧 (1.4.1)
2014 年发布, 已停止官方支持。建议升级到 lwIP 2.x 以获得 IPv6、性能提升和安全修复。
User/ETH/lwip-1.4.1/
⚡ 低风险 / 建议
vTaskStart 为空循环任务
创建后仅执行 vTaskDelay(200), 无实际功能。建议移除或复用该任务资源。
全局变量过多
main.c 顶部大量全局变量 (MAC 地址, IP 地址, 状态标志等), 缺乏模块封装。
硬编码地址
多处直接使用 0x1FF0F7E8, 0x24077000, 0x10000000 等地址, 建议宏定义 + 注释。
条件编译混乱
#if 0 / #if 1 大量存在, 包含注释掉的旧代码和调试代码, 建议清理。
BCM 任务栈可优化
栈 64 KB 是其他任务的 16~64 倍, 建议用 uxTaskGetStackHighWaterMark 测量实际使用量。
ARM9 参考代码残留
ARM9_ftu_net_pro 目录包含原 AT91RM9200 平台 BSP 参考代码, 建议清理。