system_config.h
源文件路径:
data/system_config/system_config.h所属模块:data/system_config(系统配置的 Flash 页映射、功能位定义与初始化/恢复接口) 代码行数:838
1. 文件职责
本文件是 EMS "配置持久化层"的契约头文件,定义了三类东西:
- EEPROM 模拟区(内部 Flash 末段)的页分配表:以宏形式把 4071~4095 号 4 KB 扇区一一对应到业务含义(SN/密码、逻辑配置、电表、电池、逆变器、能量、网络、干接点、Modbus、CT、充电桩、时间控制扩展、自定义配置、系统备份)。任何新增配置页都必须在这里加宏并同步
MESSAGES_SIZE与SYSTEM_MESSAGES_PAGE_ID_U,见data/system_config/system_config.h:49的注释。 - 落盘结构体的内存布局:
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 扇区尺寸,从而保证"一个结构体块 = 扇区内的整数个槽位"这种多副本写入策略成立。 - 初始化/恢复/保存三组函数的原型:
*_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 既是首页号也是位图基准,因此存在两条固定换算:
- 保存任务的位号:
page_id = page - SYSTEM_STARTE_PAGE(实现于system_config.c:2691),页 4071→位 0,页 4095→位 24。 - EEPROM 故障标志的位号:
bit = addr - SYSTEM_STARTE_PAGE(实现于data/fault_warn_log/fault_warn_log.c:2084),有效范围由[SYSTEM_STARTE_PAGE, SYSTEM_DATA_BACKUP_PAGE]钳住。 - 物理地址:
byte_addr = page * 4096,首页 4071 → 0xFE7000,末页 4095 → 0xFFF000,正好落在FEEPROM_SECTOR_ADDR_START=0xFE7000~FEEPROM_SECTOR_ADDR_END=0xFFFFFF区间内(hardware/flash/feeprom.h:16-17)。
MESSAGES_SIZE(=25) 必须等于 SYSTEM_DATA_BACKUP_PAGE - SYSTEM_STARTE_PAGE + 1。SYSTEM_MESSAGES_PAGE_ID_U 用 32 位位图装 25 个页,位 25..31 为上界余量与保留。新增页时必须同时改这三处,注释已明确提示(:49)。
4.2 功能位的两套表示与"能力表 → 持久配置"的同步
功能开关在代码里有两种存在形式:
SYSTEM_BASE_PARA_T.u_system_function1/2:已持久化的用户/安装商配置,随 4071 页写 Flash,并被net/ems.c:2029-2030上传云端。SYSTEM_FUNCTION_PARA_T.u_system_function1/2+t_dev_fun+t_paradev_fun:运行期能力表,由midware/auxiliary/system_aux.c的device_function_init()按检测到的逆变器子型号(S5/B5/S3.6/B3.6/S6/S8/S10/B10 等)逐位置 1 或 0。同步逻辑在system_aux.c:1719-1725:能力表与持久配置不一致时,把能力表整字写回g_t_system_base_info.u_system_function1,后续由保存任务落盘。
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. 依赖关系
- 依赖:
includes.h(uCOS-II 与工程通用定义)、chip.h(基础类型)、pcf8563.h(RTC_DateTime_Simp)、debug.h(断言宏与FLASH_SECTOR_SIZE)。 - 被依赖:
data/system_config/system_config.c、data/data.c、data/resume_data/flash/flash_data_store.c、hmi/key.c、net/ems.c、net/server.c、midware/auxiliary/system_aux.c、midware/*(凡调用save_job_post或读写四项全局变量者)。由于logic/logic.h、midware/bms/bms.h等自己的配置结构体也依赖ASSERT_FLASH_SECTOR_SIZE,本头文件实际是整条配置链的根。
7. 备注与风险点
- 两处宏名拼写错误:
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 余处引用,改名需全局替换。 - 对新增页的约束完全靠人工维护:
MESSAGES_SIZE、SYSTEM_MESSAGES_PAGE_ID_U位域、页宏三者必须同步,且没有任何编译期断言把它们绑在一起;一旦漏改,save_job_post会把位号写到 25..31 的保留位上(功能仍"正常",但去重语义错位)。 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位置)时必须复核,否则云端上报的功能字与页面位图会错位。SYSTEM_FUNCTION_PARA_T内部字段名与SYSTEM_BASE_PARA_T重复:两个结构体都含u_system_function1/2,一个是运行期能力表、一个是持久配置,命名上没有区分,阅读时极易混淆(实际语义差异见第 4.2 节)。SYSTEM_FUNCTION2_U全是无意义位名(bit0..bit63):工程里几乎未使用,属于纯占位;它的存在会随 Flash 布局一起固化,若要启用必须给位起名而不能改顺序。- 保留数组长度是"凑数"而来:
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这类版本标志来兼容。 u8_factory_flag/u8_flash_renewal_flag语义没有在头文件里注释:只能从system_config.c:108/2933和flash_data_store.c:2809-2818的使用推断。u16_rpt_interval_0xA3把上报命令字写进了字段名(:738):属于协议耦合进数据结构的写法,后续报文命令字变化会造成字段名与语义不符。