EMS 知识库
首页 / knowledge/代码解析/logic

self_test.h

源文件路径:logic/self_test.h 所属模块:logic(能量调度核心 —— 电网电表接线自检) 代码行数:57

1. 文件职责

本文件是 logic/self_test.c 的数据契约头文件,为「安装接线自检」功能提供状态枚举、采样缓存结构与全局运行表。自检的物理含义是:EMS 依次执行待机、强制充电、强制放电三个阶段,在每个阶段对电网电表、PV 电表、逆变器三相功率连续采样 5 次,再通过比较三组功率的一致性判断电网电表是否断线或接线错位。本文件只声明数据结构与一个全局变量 g_t_self_test,不含任何函数原型——连 self_test.c 自己实现的四个函数都没有在此登记(system_self_test() 的原型被放在 logic/logic.h:699)。使用方是 logic/logic.c(在 SELF_TEST_CHARGE_MODE 分支调用)与 logic/self_test.c 本体。

2. 关键数据结构与宏

名称类型说明
__SELF_TEST_H__宏include guard
DEBUG_HMI宏值 0,自检过程的 HMI 调试开关;本文件与 self_test.c 中均未被实际使用
EWMA_ALPHA宏值 0.5,EWMA(指数加权移动平均)滤波系数,传给 calculate_dynamic_compensation()
SAMPLE_COUNT宏值 5,每个通道在一个阶段内采样的次数,同时决定采样数组第二维长度
SELF_STATE枚举自检状态机状态:SELF_STATE_START(0)、SELF_STATE_STANDING、SELF_STATE_STANDING_RECORD、SELF_STATE_CHARGE、SELF_STATE_CHARGE_RECORD、SELF_STATE_DISCHARGE、SELF_STATE_DISCHARGE_RECORD、SELF_STATE_END
SELF_RUN_TABLE_T结构体自检运行表,字段见下表

SELF_RUN_TABLE_T 字段分解:

字段类型说明
self_state_flagu8当前自检状态,取值来自 SELF_STATE;self_test.c 用它驱动 switch 状态机
s32_pgrid_meter_offset1[4]s32[4]待机阶段电网电表 4 相(A/B/C/总)功率 EWMA 均值
s32_ppv_meter_offset1[3]s32[3]待机阶段 PV 电表 3 相功率 EWMA 均值
s32_pinv_offset1[3]s32[3]待机阶段逆变器 3 相功率 EWMA 均值
s32_pgrid_meter_offset2[4]s32[4]充电阶段电网电表功率 EWMA 均值
s32_ppv_meter_offset2[3]s32[3]充电阶段 PV 电表功率 EWMA 均值
s32_pinv_offset2[3]s32[3]充电阶段逆变器功率 EWMA 均值
s32_pgrid_meter_offset3[4]s32[4]放电阶段电网电表功率 EWMA 均值
s32_ppv_meter_offset3[3]s32[3]放电阶段 PV 电表功率 EWMA 均值
s32_pinv_offset3[3]s32[3]放电阶段逆变器功率 EWMA 均值
s32_grid_power_samples[4][5]s32[4][SAMPLE_COUNT]电网电表原始采样环形区(4 相 × 5 次),每阶段开始前被 memset 清零
s32_pv_power_samples[3][5]s32[3][SAMPLE_COUNT]PV 电表原始采样区(3 相 × 5 次)
s32_inv_power_samples[3][5]s32[3][SAMPLE_COUNT]逆变器原始采样区(3 相 × 5 次)
g_t_self_test全局变量(extern)SELF_RUN_TABLE_T 类型,定义于 logic/self_test.c:25,全工程唯一自检运行实例

3. 函数清单

本文件不含任何函数声明或定义,也不含 static inline、函数指针或回调类型。

logic/self_test.c 中实际实现但未在本头文件声明的函数有 4 个:

函数名实际定义位置说明
calculate_dynamic_compensationself_test.c:37EWMA 滤波求均值
system_self_test_dataself_test.c:54单阶段采样并求均值
system_self_test_resultself_test.c:107根据三阶段均值判定接线故障
system_self_testself_test.c:240自检状态机主入口(原型声明在 logic/logic.h:699)

4. 核心逻辑解析

本文件为纯数据结构声明文件,无可执行逻辑。其设计意图与约束要点如下:

4.1 数组维度与采样通道的约定

三类缓存的维度并不一致,这是硬件通道数差异的直接反映:

缓存第一维含义
s32_grid_power_samples[4] / s32_pgrid_meter_offset*[4]4电网电表 A、B、C 三相 + 第 4 个「总功率」通道(s32_self_test 中由 PHASE_T 采样)
s32_pv_power_samples[3] / s32_ppv_meter_offset*[3]3PV 电表仅 A、B、C 三相,无总功率通道
s32_inv_power_samples[3] / s32_pinv_offset*[3]3逆变器 3 相功率,来源是 g_t_logic_info 的 s32_pinva/b/c 而非独立采样设备

因此索引 [3] 只在电网侧合法;self_test.c:177、self_test.c:200 的单相分支里 s32_pgrid_meter_offset*[3](总功率)被用作主要判据,而 PV/逆变器侧始终只用 [0..2]。

4.2 三阶段命名与索引的对应关系

offset1 / offset2 / offset3 三个后缀不是同一阶段的重复,而是三个时间阶段的快照:

判定逻辑建立在「充/放期间电网电表读数应当按逆变器功率反向变化」这一关系上,因此三个阶段的均值必须分别保存而不能复用同一组数组。

4.3 定时 / uCOS-II 配合

本文件不声明任何任务、信号量、事件标志或消息邮箱。self_test.c 通过 OSTimeGet() 自计时(OS_TICKS_PER_SEC = 1000,见 UCOSII/uCOS-CONFIG/os_cfg.h:51,故返回值单位为毫秒),不使用阻塞等待,因此自检状态机是被 logic 任务周期性轮询推进的,而非独立任务。

4.4 通信协议帧格式

本文件不涉及通信协议,也不定义任何帧结构或校验字段。

5. 对外接口

导出(供外部使用):

名称类型使用方
g_t_self_test全局变量仅 logic/self_test.c 自身读写(self_test.c 内 60 余处引用);logic/logic.c 不直接访问其字段
SELF_STATE枚举类型logic/self_test.c:247 的 switch(g_t_self_test.self_state_flag)
SELF_RUN_TABLE_T结构体类型logic/self_test.c:25 定义实例
EWMA_ALPHA / SAMPLE_COUNT宏logic/self_test.c 的采样与滤波调用点
DEBUG_HMI宏当前无使用点

被调用(本文件引用的符号):仅 <includes.h>(self_test.h:12),用于取得 u8/s32 等基础类型。不引用任何函数或全局变量。

6. 依赖关系

依赖:

被依赖(全部 include 点):

值得注意的是:本头文件声明的 g_t_self_test 实际上只被其配套的 .c 使用,是一个「只为单一编译单元服务」的公开变量,理论上可以改为 static 并移入 .c。

7. 备注与风险点

  1. GBK→UTF-8 转换不完整,注释已损坏:self_test.h:16 的 EWMA_ALPHA 注释与 self_test.h:33 的 self_state_flag 注释是 U+FFFD(EF BF BD)替换字符与残留 GBK 字节的混合体。例如 :33 一行的字节序列里还留着 CB B2(「滤」)、D2 BB(「一」)、CE BD(「位」)、C3 B5(「枚」),说明这是一次有损转换的遗留产物。可推断原注释为「EWMA 滤波器系数」与「第一次进入调用的(状态)」,但已无法从文件中可靠还原。建议用原始仓库副本重新转码,不要在此基础上继续编辑中文注释。
  2. 头文件不声明任何函数:self_test.c 导出了 4 个全局函数,其中 3 个(calculate_dynamic_compensation、system_self_test_data、system_self_test_result)在全工程没有任何原型声明,属于「隐式声明」使用。虽然目前它们只被同一个 .c 调用(都在 self_test.c 内部,定义顺序在前),但一旦其它文件要复用就会触发编译告警或类型不匹配。system_self_test() 被放在 logic.h:699 声明,模块归属与文件归属不一致。
  3. DEBUG_HMI 是死宏:定义为 0 但全工程无引用点(self_test.c 中只有 calculate_dynamic_compensation 等函数无 #if DEBUG_HMI)。属版本遗留代码。
  4. 文件头注释是复制粘贴残留:self_test.h:2 写的是 @file :key.h,与文件名不符;@version、@date、@brief 均为空。无功能影响,但会干扰按文件检索。
  5. 采样通道数硬编码:[4] 与 [3] 直接写在数组维度里,没有对应的宏。若要支持 4 相电网或双路 PV 表,必须改结构体布局,进而影响 self_test.c 里所有 [0..3] 下标——属于易错点。
  6. SAMPLE_COUNT 与 EWMA_ALPHA 无取值范围约束:calculate_dynamic_compensation() 只做 samples[0] 起算的迭代,alpha 未做 [0,1] 校验;count 若大于 SAMPLE_COUNT 会越界读(当前调用点均传 SAMPLE_COUNT,属巧合安全)。
  7. 无 CRC / 持久化字段:SELF_RUN_TABLE_T 不参与 Flash 存储(未出现在 data/resume_data 相关结构里),掉电后自检进度丢失,self_state_flag 从 0(SELF_STATE_START)重新开始。符合自检功能的一次性语义,但意味着复位会打断自检且不报错。