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

data.h

源文件路径:data/data.h 所属模块:data(数据管理,EMS 故障字与复位接口) 代码行数:137

1. 文件职责

data/data.h 是 data/data.c 的对外契约头文件,给全工程提供两样东西:

一是EMS 侧故障字的数据表示。它用枚举 EMS_FAULT_E 定义 30 个 EMS 故障的位序号,用联合体 EMS_FAULT_U 给出同一 32 位字的三种访问视图(整字 / 分字节 / 具名位域),再包成 EMS_TAB_T,全局实例是 g_t_ems_info。所有模块置位时只需知道自己那一位的序号,读取方可以整字比较(故障日志)也可以逐位取用(LED、Modbus 寄存器)。

二是延迟复位请求与故障位读写的函数原型:task_system_data 任务入口、ems_read_fault_code / ems_set_fault_bit,以及 meter_reset / custom_info_reset / energy_reset / factory_reset / set_ems_reset / resume_flash_reset 六个复位请求接口。

它处在数据流的"公共词汇表"位置:不含逻辑,被 data/fault_warn_log、hmi/led.c、logic/*、net/ems.c、midware/* 等大量文件包含。

2. 关键数据结构与宏

名称类型(结构体/枚举/宏/联合体)说明
__DATA_H__宏头文件保护宏(data/data.h:9)
DEBUG_DATA宏取值 0(data/data.h:16),为 1 时 task_system_data 累加任务运行计数
ErrLog_t结构体1 字节对齐打包(#pragma pack(1),data/data.h:19/120),成员 u8 p_write 与 u8 cnt。cnt 表示历史故障日志条数,p_write 已成为无引用的遗留字段;原 LogBuf[10][16] 被注释(data/data.h:24)
EMS_FAULT_E枚举EMS 故障位序号,0..29(data/data.h:27-65):EMS_FAULT_NET_FAULT=0 到 EMS_FAULT_MID_METER_LOST=29。末尾注释"最多32个bit"提示不要超过 32 项
EMS_FAULT_U联合体三种视图(data/data.h:67-114):u32 u32_all、u8 byteData[4]、位域 bit。位域按 BYTE0..BYTE3 排列,每字节 8 个 1 bit 成员;bit30/bit31 为保留位
EMS_TAB_T结构体只含 EMS_FAULT_U u_ems_fault(data/data.h:116-119),便于后续扩展成多字段表
error_log全局变量(extern)ErrLog_t 实例,定义在 data/data.c:32(data/data.h:122)
g_t_ems_info全局变量(extern)EMS_TAB_T 实例,定义在 data/data.c:31(data/data.h:123)

3. 函数清单

本文件为纯头文件,不含函数实现,仅声明 9 个函数原型:

函数名作用域(static/全局)说明(一句话)
task_system_data全局(声明;实现为全局函数)uCOS-II 系统数据任务入口,由 user/main.c:156 创建(data/data.h:126)
ems_read_fault_code全局(声明)返回 EMS 32 位故障字(data/data.h:127)
ems_set_fault_bit全局(声明)按位序号置位/清位 EMS 故障字(data/data.h:128)
meter_reset全局(声明)清电表与 CT 累计电量并投递保存任务(data/data.h:130)
custom_info_reset全局(声明)请求复位自定义配置信息(data/data.h:131)
energy_reset全局(声明)请求清零能量统计数据(data/data.h:132)
factory_reset全局(声明)请求恢复出厂设置(data/data.h:133)
set_ems_reset全局(声明)请求 EMS 软复位(data/data.h:134)
resume_flash_reset全局(声明)请求擦除断电续传运行数据(data/data.h:135)

4. 核心逻辑解析

本文件无执行逻辑,此处说明两个数据表示的约定。

4.1 故障字位序约定(枚举 ↔ 位域 的对齐关系)

EMS_FAULT_E 与 EMS_FAULT_U.bit 的对应关系是按声明顺序一一对齐的,这一点是整套故障机制能工作的前提:

位号EMS_FAULT_E 枚举名EMS_FAULT_U.bit 成员备注
0EMS_FAULT_NET_FAULTu8_net_fault
1EMS_FAULT_RTC_FAULTu8_rtc_fault由 hardware/pcf8563/pcf8563.c:90 直接读写
2EMS_FAULT_EEPROM_FAULTu8_eeprom_fault由 data/data.c:228/232 的 ems_set_fault_bit(2,·) 维护
3EMS_FAULT_INV_LOSTu8_inv_lost
4-7EMS_FAULT_GRID_METER_LOST / PV_METER_LOST / BMS_LOST / BAT_VOLT_LOW同名 u8_*
8-15EMS_FAULT_BACKUP_OVERLOAD … EMS_FAULT_EXTENSION_CAN_ERRORbackup_overload … u8_extension_can_error注意 8/9/10/11/12 这几个成员名没有 u8_ 前缀(data/data.h:85-89),只是命名不一致,位序不受影响
16-23EMS_FAULT_INV_TYPE_NOT_SPECIFIED … EMS_FAULT_INV_INITIALIZATION_FAILEDinv_type_not_specified 等
24-29EMS_FAULT_EPO_TRIGGER … EMS_FAULT_MID_METER_LOSTepo_trigger … u8_mid_meter_lost
30-31无枚举名bit30 / bit31保留

字节序:结构体由 4 个 u8 位域容器顺序组成(每容器 8 位),在 ARM Cortex-M4 小端下,位 0 落在 byteData[0] 的 bit0。data/fault_warn_log/fault_warn_log.c:552-565 正是依赖 byteData[] + BIT_VALUE/BIT_IS_SET 宏做逐位比较。

4.2 打包与尺寸约束

#pragma pack(1)(data/data.h:19)到 #pragma pack()(data/data.h:120)之间所有结构体按 1 字节对齐。这保证这些结构体可以直接整块写进 Flash 页而不受编译器对齐填充影响。本文件中的 EMS_TAB_T 恰好是 4 字节,ErrLog_t 是 2 字节。

本文件不涉及通信帧格式、状态机、定时器与 uCOS-II 同步对象。

5. 对外接口

导出内容:

名称类型使用者
g_t_ems_info全局变量data/fault_warn_log/fault_warn_log.c(2028、2151、2155、2167)、hardware/pcf8563/pcf8563.c:90、logic/logic.c:390-395、net/ems.c:676、midware/interface/modbus/modbus.c:3061/3737、midware/interface/dry_node/dry_node.c:1878、midware/bms/bms.c:1237/3284、midware/meter/meter.c:7043/7047、midware/inverter/set/set_comm_usart_s5.c:1077
error_log全局变量data/fault_warn_log/fault_warn_log.c:1556-1557(写 cnt)、hmi/key.c:4166、hmi/ui/ui_history_error_log.c:196-216(读 cnt 做菜单边界)
9 个函数原型函数声明见第 3 节

本文件自身调用的外部资源:仅 #include "chip.h"(data/data.h:13),用于取得 u8/u16/u32/s8 等基础类型定义。不引用 g_t_logic_info、g_t_config_data 等其他全局变量。

6. 依赖关系

7. 备注与风险点

  1. 枚举名与位域成员名不总是同名:位 8-23 中的 9 个位域成员(backup_overload、inv_slave_lost、inv_master_lost、parallel_comm_error、parallel_mode_differ、inv_type_not_specified、sampling_anomaly、inv_satuse_abnormal_bat_shutdown、parallel_host_lost、parallel_form_lost、pv_charger_host_lost、inv_initialization_failed、epo_trigger、afci_self_check_fault)缺少 u8_ 前缀,按名字检索位域时容易漏查。
  2. inv_satuse_abnormal_bat_shutdown 拼写错误:应为 status,data/data.h:98。一旦被外部文件引用,改名会连带改动多处。
  3. 枚举与位域靠人工保序:两处定义分离,新增故障位时若只改枚举不改位域(或反之)会造成静默错位,且没有 STATIC_ASSERT 之类的编译期校验。
  4. 位域成员类型用 u8 承载 32 位联合体:这是 Keil ARMCC/GCC 下常见写法,依赖编译器把 4 个 u8 位域容器连续排布;换编译器或换 #pragma pack 位置时需要重新确认 u32_all 与 byteData[] 的映射。
  5. ErrLog_t.p_write 与注释掉的 LogBuf:属于版本遗留,若后续打算恢复日志缓存,需要同步修改 #pragma pack 块内的尺寸,并注意 error_log 还有 flash_data_store / hmi 的既有引用。
  6. 文件头注释错误:data/data.h:2 写的是 @file :com485do.h,与实际文件名不符(从其他文件复制模板所致)。
  7. u8 byteData[sizeof(u32)/sizeof(u8)] 写法较绕,直接写 u8 byteData[4] 更清晰;目前依赖 u32 为 4 字节这一前提。