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

system_config.h

源文件路径:data/system_config/system_config.h 所属模块:data/system_config(系统配置的 Flash 页映射、功能位定义与初始化/恢复接口) 代码行数:838

1. 文件职责

本文件是 EMS "配置持久化层"的契约头文件,定义了三类东西:

  1. EEPROM 模拟区(内部 Flash 末段)的页分配表:以宏形式把 4071~4095 号 4 KB 扇区一一对应到业务含义(SN/密码、逻辑配置、电表、电池、逆变器、能量、网络、干接点、Modbus、CT、充电桩、时间控制扩展、自定义配置、系统备份)。任何新增配置页都必须在这里加宏并同步 MESSAGES_SIZE 与 SYSTEM_MESSAGES_PAGE_ID_U,见 data/system_config/system_config.h:49 的注释。
  2. 落盘结构体的内存布局:SYSTEM_BASE_PARA_T、STSTEM_CUSTOM_PARA_T、SYSTEM_BACKUP_TABLE_T 三个"整页可回写"结构,以及承载功能开关位的多个 64 位/32 位联合体(SYSTEM_FUNCTION1_U、SYSTEM_FUNCTION2_U、DEVICE_FUNCTION_U、PARALLELISMDEVICE_FUNCTION_U)。所有结构都在 #pragma pack(1) 区间内,并配有 STATIC_ASSERT 要求结构体大小能整除 Flash 扇区尺寸,从而保证"一个结构体块 = 扇区内的整数个槽位"这种多副本写入策略成立。
  3. 初始化/恢复/保存三组函数的原型:*_info_init()(出厂值写入)、system_info_restore()(上电从 Flash 恢复)、save_job_post() / save_energy_data() / system_config_data_save()(异步保存调度)。

数据流位置:system/board_init/board_init.c:250 在上电早期调用 system_info_restore() 把 Flash 内容灌进 g_t_logic_info、g_t_meter、g_t_bat_info、g_t_inv_info、g_t_ct、g_t_modbus_config、IP_Address 等全局变量;运行期各模块通过 save_job_post(page) 把"这一页脏了"投进队列,由 task_system_data 调用 system_config_data_save() 真正落盘。

2. 关键数据结构与宏

名称类型(结构体/枚举/宏/联合体)说明
DEBUG_SYSTEM_CONFIG宏取值 0(:18),为 1 时打开各 init/restore 的 printf 与 ShowData() 十六进制转储
CONFIG_INFO_HEAD宏0xAA55(:20),所有配置结构体首字段,用于识别"这个槽位有合法数据"
SYSTEM_STARTE_PAGE宏4071(:22),EEPROM 模拟区首页,同时是 save_job_post(msg) 中"msg - 基址 = 位号"的基准;对应字节地址 0xFE7000(hardware/flash/feeprom.h:16)
SYSTEM_BASE_PARA_PAGE宏4071,SN/语言/密码/功能位(:23)
LOGIC_CONFIG_PAGE宏4072,逻辑配置主表(:24)
METER_CONFIG_PAGE宏4073,电表配置与分相累计电量(:25)
BATTERY_CONFIG_PAGE宏4074(:26)
INVERTER_CONFIG_PAGE宏4075(:27)
ENERGY_INFO_PAGE宏4076,能量统计(:28)
NET_PARA_PAGE宏4077,网络参数(:29)
DRY_NODE_PARA_PAGE宏4078,干接点(:30)
MODBUS_CONFIG_PAGE宏4079(:31)
CT_CONFIG_PAGE宏4080,CT 校准表(:32)
CT_ENERGY_PAGE宏4081,CT 累计电量(:33)
EVC_CONGIF_PAGE宏4082,EVC 一代充电桩配置(拼写错误,丢了字母 G,:34)
EVC_SETTING_PAGE宏4083(:35)
EVC_II_SETTING1_PAGE … EVC_II_SETTING4_PAGE宏4084 / 4085 / 4086 / 4089,EVC 二代 4 路充电桩配置(:36-41)
BATTERY_EXTEND_CONFIG_PAGE宏4087,电池扩展信息(单体软件版本、SN)(:39)
STSTEM_CUSTOM_CONFIG_PAGE宏4088,自定义配置(拼写错误,丢了 Y,:40)
STSTEM_CUSTOM_CONFIG_BACKUP_PAGE宏4090,自定义配置备份(:42)
LOGIC_CONFIG_PAGE2/3/4宏4091 / 4092 / 4093,时间控制扩展 1/2/3(:43-45)
SYSTEM_DATA_BACKUP_PAGE宏4095,最后一页,保存 SN/MAC/IP/逆变器型号的系统级备份(:47)
MESSAGES_SIZE宏25(:49),保存队列长度、内存块数量,以及 save_job_post 的位号上界;等于页总数 4095-4071+1
OEM_LIST_E枚举OEM 厂商枚举:OEM_ALPHAESS=0 … OEM_PEIMAR,末尾 OEM_COMPANY_MAX(:53-63)
SAVE_JOB_T结构体保存任务报文(:66-72),u8 page_id(位号)+ u16 page(页号)+ u32 tim_s(投递时刻 tick)+ u32 tim(耗时 tick),pack(1) 后 11 字节
SYSTEM_MESSAGES_PAGE_ID_U联合体u32 u32_all + 位域 bit(:74-116),每一位对应一个页是否"已有待保存任务",用于去重;位 24 = system_data_backup_page,bit25..bit31 保留
SYSTEM_FUNCTION1_U联合体u64 u64_all + 64 个功能位(:118-204),如远程升级、自发自用、FCAS、BackupBox、并机、油机、Grid-Forming、南澳调度、Modbus RTU/TCP、DRMS、LCD/LED、各类接口
SYSTEM_FUNCTION2_U联合体u64 u64_all + bit0..bit63 纯占位位域(:206-292),是"还没定义含义的保留位池"
DEVICE_FUNCTION_U结构体8 个 u32 功能组(:294-616):ems_fun_u、ems_fun_2_u、ems_fun_3_u、bms_fun_u、inv_fun_u、meter_fun_u、evc_fun_u、grid_regulation_u,每组末字节 *_table 留作扩展编号
PARALLELISMDEVICE_FUNCTION_U结构体并机场景的两个 32 位功能组 para_ems_fun_u / para_ems_fun2_u(:618-714),当前仅定义了 u8_en_para_force_discharge、u8_para_grid_meter_limit 两位
SYSTEM_FUNCTION_PARA_T结构体运行期"功能能力表"(:716-722):u_system_function1 + u_system_function2 + t_dev_fun + t_paradev_fun,全局实例 g_system_function_info,由 midware/auxiliary/system_aux.c 的 device_function_init() 按逆变器型号填充
SYSTEM_BASE_PARA_T结构体4071 页布局(:724-742):u16_head、s8_sn[16]、u16_user_password、u8_language、u16_oem_flag、u8_factory_flag、u_system_function1、u_system_function2、s8_e_link_password[16]、u8_flash_renewal_flag、RTC_DateTime_Simp t_install_date(3 字节:日/月/年)、u16_rpt_interval_0xA3、u8_reserved[64]、u16_crc_code;合计 128 字节(4096/128=32 槽位)
STSTEM_CUSTOM_PARA_T结构体4088/4090 页布局(:746-770):u16_head、显示标志/类型、s8_system_modle[33]、登录标志与公司名/密码(各 33)、s8_socket_point[65]、socket 端口与加密端口、u8_reserve[74]、u16_crc_code;合计 256 字节(16 槽位)
SYSTEM_BACKUP_TABLE_T结构体4095 页布局(:773-798):u16_head、s8_sn[16]、u8_mac[6]、u8_inv_type、u8_ip_method、u8_server_point、4 组 IP/网关/掩码(各 4 个 u16)、u8_reserve[203]、u16_crc_code;合计 256 字节(16 槽位)
STATIC_ASSERT / ASSERT_FLASH_SECTOR_SIZE宏定义在 midware/debug/debug.h:16/19,后者等于 FLASH_SECTOR_SIZE = 4*1024(hardware/flash/flash.h:27);本文件在 :744、:771、:799 静态断言三个结构体大小整除 4096
g_t_system_base_info全局变量(extern)4071 页的 RAM 镜像(:803)
g_system_custom_info全局变量(extern)4088 页的 RAM 镜像(:804)
g_system_function_info全局变量(extern)运行期功能能力表(:805)
g_system_msg_page_id全局变量(extern)保存任务去重位图(:806)

3. 函数清单

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

函数名作用域(static/全局)说明(一句话)
ui_info_init全局(声明,:808)重置密码/语言并写回 4071 页
logic_config_info_init全局(声明,:809)逻辑配置主表恢复出厂值
logic_config_extend1_info_init全局(声明,:810)时间控制扩展 1 出厂值
logic_config_extend2_info_init全局(声明,:811)时间控制扩展 2 出厂值
logic_config_extend3_info_init全局(声明,:812)时间控制扩展 3 出厂值
meter_config_info_init全局(声明,:813)电表配置出厂值
bat_config_info_init全局(声明,:814)电池配置出厂值
bat_extend_config_info_init全局(声明,:815)电池扩展配置出厂值
inverter_config_info_init全局(声明,:816)逆变器配置出厂值
ct_energy_info_init全局(声明,:817)CT 累计电量清零
energy_info_init全局(声明,:818)能量统计清零
dry_node_info_init全局(声明,:819)干接点配置出厂值
net_ip_method_init全局(声明,:820)网络地址方式复位为 DHCP
modbus_config_info_init全局(声明,:821)Modbus 配置出厂值
evc_config_info_init全局(声明,:822)EVC 一代充电桩配置出厂值
evc_setting_info_init全局(声明,:823)EVC 充电参数出厂值
evc_ii_single_config_info1_init全局(声明,:824)EVC 二代第 1 路出厂值
evc_ii_single_config_info2_init全局(声明,:825)EVC 二代第 2 路出厂值
evc_ii_single_config_info3_init全局(声明,:826)EVC 二代第 3 路出厂值
evc_ii_single_config_info4_init全局(声明,:827)EVC 二代第 4 路出厂值
system_custom_info_init全局(声明,:828)自定义配置出厂值
system_custom_backup_info_init全局(声明,:829)自定义配置备份重建
system_backup_info_init全局(声明,:830)系统级备份页重建(SN/MAC/IP/型号)
net_info_init全局(声明,:831)网络信息出厂值(MAC 与服务器点保留)
system_info_restore全局(声明,:832)上电时把全部配置页恢复进 RAM,单页失败则回退出厂值
save_job_init全局(声明,:833)创建保存队列与内存分区
save_job_post全局(声明,:834)投递一次"某页需保存"任务,带去重
save_energy_data全局(声明,:835)一次性投递能量/CT/电表三页保存任务
system_config_data_save全局(声明,:836)从队列取出任务并真正写 Flash(含定时能量保存与备份页刷新)

4. 核心逻辑解析

本文件无执行逻辑,此处说明它规定的两条关键约定。

4.1 页号 ↔ 位号 的换算约定

SYSTEM_STARTE_PAGE 既是首页号也是位图基准,因此存在两条固定换算:

MESSAGES_SIZE(=25) 必须等于 SYSTEM_DATA_BACKUP_PAGE - SYSTEM_STARTE_PAGE + 1。SYSTEM_MESSAGES_PAGE_ID_U 用 32 位位图装 25 个页,位 25..31 为上界余量与保留。新增页时必须同时改这三处,注释已明确提示(:49)。

4.2 功能位的两套表示与"能力表 → 持久配置"的同步

功能开关在代码里有两种存在形式:

DEVICE_FUNCTION_U 的 8 个 u32 组是这一能力矩阵的"分模块视图"(EMS/BMS/INV/METER/EVC/并网法规各自一组),每组的 BYTE3 是 u8_xxx_table 扩展编号,属于为后续版本预留的"组内编号"。

4.3 尺寸约束为什么必须成立

feeprom_write() 的写入策略是"读整扇区 → 从后往前找到第一个首字节为 0x55 / 0xAA 的槽位 → 擦扇区 → 把整块数据回写并把新数据放到下一个可用槽位",即以"整数个槽位"为单位做追加写(hardware/flash/feeprom.c:180-188 的定位循环)。因此 sizeof(结构体) 必须整除 4096,否则槽位会跨扇区边界越界。本文件的 STATIC_ASSERT(ASSERT_FLASH_SECTOR_SIZE % sizeof(...) == 0)(:744、:771、:799)就是编译期守卫;同工程其它配置结构体的同类断言散落在各自的头文件中(logic/logic.h、midware/bms/bms.h、midware/ethernt/ethernet.h、midware/evc/*.h、midware/meter/*.h、midware/interface/*.h 等)。

4.4 CRC 与校验字段约定

三个落盘结构体都以 u16_crc_code 结尾,由调用方用 GetCrcCode_Modbus((u8 *)&结构体, sizeof(结构体) - 2) 计算(Modbus CRC16,实现在 common/crc.c:144),恢复时重新计算并比对,比对失败即判定该槽位无效。头字段 u16_head = CONFIG_INFO_HEAD (0xAA55) 同时被 feeprom_read() 的定位逻辑用作"槽位有效"标记,因此是一个"双重校验"设计。

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

5. 对外接口

名称类型使用者
g_t_system_base_info全局变量data/resume_data/flash/flash_data_store.c:2809/2818、hmi/key.c:8911-8912、midware/auxiliary/system_aux.c:1719-1725/2560-2566、net/ems.c:2029-2030、system_config.c 内部
g_system_custom_info全局变量system_config.c(本页写回与备份比较);外部通过 STSTEM_CUSTOM_PARA_T 的 socket/登录字段读取(net/、hmi/ 相关文件)
g_system_function_info全局变量midware/auxiliary/system_aux.c(填充)、midware/ethernt/wireless/wifi/e_linker_wifi.c:319/343/363/439、midware/evc/evc_ii.c:655/674、net/ems.c:2108、net/server.c:4885
g_system_msg_page_id全局变量仅 system_config.c 的 atomic_check_and_set_bit / atomic_clear_bit / save_job_post / save_job_pend 使用
28 个函数原型函数声明data/data.c(复位流程调用)、data/resume_data/flash/flash_data_store.c(save_job_post)、hmi/key.c(大量 save_job_post)、net/server.c、logic/logic.c、midware/*(保存任务投递)

本文件自身调用的外部资源:#include "includes.h"、"chip.h"、"pcf8563.h"(取 RTC_DateTime_Simp)、"debug.h"(取 STATIC_ASSERT / ASSERT_FLASH_SECTOR_SIZE),见 :13-16。

6. 依赖关系

7. 备注与风险点

  1. 两处宏名拼写错误:EVC_CONGIF_PAGE(:34,应为 CONFIG)、STSTEM_CUSTOM_CONFIG_PAGE / STSTEM_CUSTOM_CONFIG_BACKUP_PAGE(:40、:42)以及结构体名 STSTEM_CUSTOM_PARA_T(:746,应为 SYSTEM)。已扩散到 system_config.c 与其它文件的 100 余处引用,改名需全局替换。
  2. 对新增页的约束完全靠人工维护:MESSAGES_SIZE、SYSTEM_MESSAGES_PAGE_ID_U 位域、页宏三者必须同步,且没有任何编译期断言把它们绑在一起;一旦漏改,save_job_post 会把位号写到 25..31 的保留位上(功能仍"正常",但去重语义错位)。
  3. u16/u8 位域在 32/64 位联合体中的可移植性:SYSTEM_FUNCTION1_U/SYSTEM_FUNCTION2_U 用 64 个 u8 型 1 位位域拼出 u64,SYSTEM_MESSAGES_PAGE_ID_U 用 32 个 u8 型 1 位位域拼出 u32,都隐式依赖编译器把位域按声明顺序连续紧密排布。换编译器(或调整 #pragma pack 位置)时必须复核,否则云端上报的功能字与页面位图会错位。
  4. SYSTEM_FUNCTION_PARA_T 内部字段名与 SYSTEM_BASE_PARA_T 重复:两个结构体都含 u_system_function1/2,一个是运行期能力表、一个是持久配置,命名上没有区分,阅读时极易混淆(实际语义差异见第 4.2 节)。
  5. SYSTEM_FUNCTION2_U 全是无意义位名(bit0..bit63):工程里几乎未使用,属于纯占位;它的存在会随 Flash 布局一起固化,若要启用必须给位起名而不能改顺序。
  6. 保留数组长度是"凑数"而来:u8_reserved[64](SYSTEM_BASE_PARA_T)、u8_reserve[74](STSTEM_CUSTOM_PARA_T)、u8_reserve[203](SYSTEM_BACKUP_TABLE_T)都是为了让总长凑成 128/256 字节。后续字段增删会直接改变这些长度,与已出厂设备写入的 Flash 内容产生布局不兼容,需要靠 u8_flash_renewal_flag、u8_reserved_flag 这类版本标志来兼容。
  7. u8_factory_flag / u8_flash_renewal_flag 语义没有在头文件里注释:只能从 system_config.c:108/2933 和 flash_data_store.c:2809-2818 的使用推断。
  8. u16_rpt_interval_0xA3 把上报命令字写进了字段名(:738):属于协议耦合进数据结构的写法,后续报文命令字变化会造成字段名与语义不符。