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_flag | u8 | 当前自检状态,取值来自 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_compensation | self_test.c:37 | EWMA 滤波求均值 |
system_self_test_data | self_test.c:54 | 单阶段采样并求均值 |
system_self_test_result | self_test.c:107 | 根据三阶段均值判定接线故障 |
system_self_test | self_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] | 3 | PV 电表仅 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 三个后缀不是同一阶段的重复,而是三个时间阶段的快照:
offset1:待机阶段(SELF_STATE_STANDING_RECORD),电池不充不放,作为基线。offset2:强制充电阶段(SELF_STATE_CHARGE_RECORD),bat_force_charge()使能。offset3:强制放电阶段(SELF_STATE_DISCHARGE_RECORD),bat_force_discharge()使能。
判定逻辑建立在「充/放期间电网电表读数应当按逆变器功率反向变化」这一关系上,因此三个阶段的均值必须分别保存而不能复用同一组数组。
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 <includes.h>(self_test.h:12)——提供u8、s32、TRUE/FALSE等基础类型与宏。
被依赖(全部 include 点):
logic/self_test.c:19- 无其他文件 include 本头文件(
logic/logic.c只通过logic.h取得system_self_test()原型,并不包含self_test.h)。
值得注意的是:本头文件声明的 g_t_self_test 实际上只被其配套的 .c 使用,是一个「只为单一编译单元服务」的公开变量,理论上可以改为 static 并移入 .c。
7. 备注与风险点
- 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 滤波器系数」与「第一次进入调用的(状态)」,但已无法从文件中可靠还原。建议用原始仓库副本重新转码,不要在此基础上继续编辑中文注释。 - 头文件不声明任何函数:
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声明,模块归属与文件归属不一致。 DEBUG_HMI是死宏:定义为0但全工程无引用点(self_test.c中只有calculate_dynamic_compensation等函数无#if DEBUG_HMI)。属版本遗留代码。- 文件头注释是复制粘贴残留:
self_test.h:2写的是@file :key.h,与文件名不符;@version、@date、@brief均为空。无功能影响,但会干扰按文件检索。 - 采样通道数硬编码:
[4]与[3]直接写在数组维度里,没有对应的宏。若要支持 4 相电网或双路 PV 表,必须改结构体布局,进而影响self_test.c里所有[0..3]下标——属于易错点。 SAMPLE_COUNT与EWMA_ALPHA无取值范围约束:calculate_dynamic_compensation()只做samples[0]起算的迭代,alpha未做[0,1]校验;count若大于SAMPLE_COUNT会越界读(当前调用点均传SAMPLE_COUNT,属巧合安全)。- 无 CRC / 持久化字段:
SELF_RUN_TABLE_T不参与 Flash 存储(未出现在data/resume_data相关结构里),掉电后自检进度丢失,self_state_flag从 0(SELF_STATE_START)重新开始。符合自检功能的一次性语义,但意味着复位会打断自检且不报错。