parallel.h
#pragma pack(1) 的强约束4.2 地址空间约定4.3 主机/从机双结构的对称关系4.4 SOC 与功率的单位约定4.5 定时/自适应时序常量5. 对外接口5.1 本文件导出5.2 本文件依赖5.3 未在头文件中导出但实际跨文件使用的全局变量6. 依赖关系7. 备注与风险点源文件路径:
midware/inverter/parallel.h所属模块:midware/inverter(逆变器中间件 / 并机) 代码行数:338
1. 文件职责
本文件是 EMS 并机(多机并联)功能的数据契约头文件。它定义了并机最大台数、通信方案自适应时间常数、SOC 均衡权重系数等编译期常量,并用 #pragma pack(1) 定义了主从机角色枚举、并机通信方式枚举、电池工况/升级标志位域联合体,以及三组核心数据结构:主机侧"组网参数表"、主机侧"运行信息表"、从机侧"组网参数 + 运行信息"。这些结构体是 CAN(parallel_comm/parallel_can.c)和 SCI/Modbus(parallel_comm/parallel_sci.c)两条并机通道的线格式映射表——通信层按字段顺序逐字节拆包/组包,业务层(parallel.c)按字段做功率分配。本文件只做声明与类型定义,不产生代码,被 parallel.c、parallel_can.c、parallel_sci.c 以及所有需要读并机汇总量(logic/、net/、midware/interface/modbus/)的文件包含。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
PARALLEL_MAX_NUM | 宏 | 16,并机最大数量,是所有 g_t_host_machine_*_info[PARALLEL_MAX_NUM] 数组的维度,也是各层 for 循环的边界 |
PARALLEL_MSTER_CHECK_TIME | 宏 | 15000(15 s),主机角色下通信方案(CAN/UART4/USART3)自适应重试切换间隔,由 interface.c 使用 |
PARALLEL_SLAVE_CHECK_TIME | 宏 | 30000(30 s),从机角色下通信方案自适应切换间隔 |
PARALLEL_BAT_SOC_CTRL_RATE_CFG | 宏 | 9,SOC 均衡权重配置值 |
PARALLEL_BAT_SOC_CTRL_RATE_SET | 宏 | (CFG < 10 ? CFG : 10) = 9,SOC 均衡中"按可用容量占比"分配的比例系数(分母 10,即 0.9) |
PARALLEL_BAT_LIMT_CTRL_RATE_SET | 宏 | 10 - PARALLEL_BAT_SOC_CTRL_RATE_SET = 1,理论上是"按功率上限占比"的权重;全工程未被引用(见第 7 节) |
PARALLEL_MODE_E | 枚举 | 机组角色:FORM_MACHINE=0(从机)/ HOST_MACHINE(主机)/ OTHER_MACHINE(未定,parallel.c 用作初值) |
PARALLEL_COM_TYPE_E | 枚举 | 并机通信方式:PARA_COM_TYPE_NONE=0、PARA_COM_TYPE_UART4、PARA_COM_TYPE_CAN、PARA_COM_TYPE_USART3、PARA_COM_TYPE_MAX |
PARALLEL_COM_CARD_STATUS_E | 枚举 | 并机通信是否依赖通信卡:PARA_COM_RELY_ON_CARD=0(靠卡/走 CAN)、PARA_COM_NO_CARD(不靠卡/走串口) |
BAT_WORK_FLAG_U | 联合体 | 从机电池工况字节:bit_bms_comm_flag:2、bit_bms_work_flag:2、bit_bms_relay_flag:2、bit_bat_force_charge_flag:2(共 8 bit,整体按 u8_bat_flag 收发) |
UPGRADE_FLAG_U | 联合体 | 升级标志字节:bit_ems_upgrade_flag:2、bit_inv_upgrade_flag:2、bit_bms_upgrade_flag:2、bit_reserved:2 |
PARALLEL_TOTAL_MACHINE_NETWORKING_T | 结构体 | 全局并机网络状态:u8_comm_success_flag(任一从机通信成功)、u8_run_machine_precept(当前尝试的通信方案)、u8_precept_change_recv_tick_flag、u32_precept_change_recv_tick、u32_precept_adaptive_tick(方案切换定时基准) |
PARALLEL_HOST_MACHINE_NETWORKING_PARAMETER_T | 结构体 | 主机侧从机档案:u8_unique_device_id[2](设备 ID 的 CRC16)、u8_mac[3](MAC 低 3 字节)、u8_parallel_addr、u8_parallel_addr_en、u8_parallel_lost_flag、u32_rcv_tick(心跳时间戳) |
PARALLEL_FROM_MACHINE_NETWORKING_PARAMETER_T | 结构体 | 从机侧自身档案:u8_parallel_addr、u8_parallel_addr_en、u8_parallel_lost_flag、u32_rcv_tick |
PARALLEL_HOST_MACHINE_RUNNING_INFO_T | 结构体 | 主机侧每台机的完整镜像,含三段:发送段控制参数(u8_sequencecontrol_mode、u8_three_unbalance_mode、u8_bb_model、u8_gc_control_en、u8_freq_dispatch_en、u8_safety/safesub、u8_inv_backup_en、u8_nn_short_detect_state、u8_drm_mode、u16_mppt_percentage、u8_set_inv_on_off、u8_set_bms_shutdown + DC/AC 总功率与三相功率设定值);接收段逆变器规格/运行数据(PV 4 路、电网/备电/逆变三相电压功率频率、母线电压电流功率、工作模式、u8_feedin_flag);电池段(容量、BAT_WORK_FLAG_U、SOC/电压/电流/功率、充放电最大功率、SN、UPGRADE_FLAG_U);系统段(u8_sys_force_charge_flag、s16_max_charge_power_limit、s16_max_dischg_power_limit、u8_bat_soc_priority_en、u16_bat_soc_full_power_threshold) |
PARALLEL_FROM_MACHINE_RUNNING_INFO_T | 结构体 | 从机侧接收到的、由主机下发的控制参数:顺序控制模式、安规/安规子项、油机使能、调频使能、BB 模式、三相不平衡模式、备电使能、N-N 短接检测、DRM 模式、MPPT 百分比、逆变器开关机、BMS 关机,以及 DC 总/三相设定、AC 总/三相设定与强制充电使能,外加 host_machine_upgrade_flag_u |
g_t_parallel_total_machine_network | 全局变量(extern) | 本头文件唯一导出的全局变量,类型 PARALLEL_TOTAL_MACHINE_NETWORKING_T,被 parallel.c、interface.c 读写 |
parallel_data_handle 等 3 个 | 函数声明 | parallel_data_handle、parallel_can_comm_handle、parallel_sci_comm_handle |
parallel_read_system_* 系列 | 函数声明 | 约 40 个"读系统级汇总量"访问器(额定功率、PV/电网/备电/逆变功率、电池 SOC/电压/功率、充放电限值、强制充电标志等),把它们乘/加后交给 logic/ |
parallel_read_*_set_* 系列 | 函数声明 | 约 20 个"读下发给逆变器的设定值"访问器(DC/AC 总与三相设定功率、强制充电使能、油机使能、调频使能) |
parallel_read_backup_en / parallel_set_backup_en | 函数声明 | 备电使能读/写,被 logic.c 调用 |
parallel_read/set_config_machine_precept | 函数声明 | 读/写持久化的并机实际通信方案 g_t_inv_info.t_config_data.u8_parallel_precept |
parallel_read/set_full_power_priority_enable | 函数声明 | 满功率优先使能读写,由 net/server.c 下发 |
parallel_read/set_bat_soc_threshold | 函数声明 | 满功率优先的 SOC 门限读写,由 net/server.c 下发 |
3. 函数清单
本文件为纯头文件,不含任何函数定义,仅有函数声明。完整声明清单如下(均在第 264-336 行):
| 函数名 | 作用域 | 说明 |
|---|---|---|
parallel_data_handle | 全局(声明) | 并机业务主入口,由逆变器任务周期调用 |
parallel_can_comm_handle | 全局(声明) | CAN 并机通信入口 |
parallel_sci_comm_handle | 全局(声明) | 串口(Modbus)并机通信入口 |
parallel_read_system_self_consumption | 全局(声明) | 读系统自发自用阈值 |
parallel_read_system_control_accuracy | 全局(声明) | 读系统控制精度 |
parallel_read_system_rated_input_power | 全局(声明) | 读系统额定充电功率(各机求和) |
parallel_read_system_rated_output_power | 全局(声明) | 读系统额定放电功率 |
parallel_read_system_rated_charge_power | 全局(声明) | 读系统额定电池充电功率 |
parallel_read_system_rated_dischg_power | 全局(声明) | 读系统额定电池放电功率 |
parallel_read_system_maxfeedin_offset_power | 全局(声明) | 读最大馈网偏置功率 |
parallel_read_system_pv_status | 全局(声明) | 读系统 PV 状态(任一机馈电即为真) |
parallel_read_system_grid_status | 全局(声明) | 读系统并网状态 |
parallel_read_system_grid_voltage | 全局(声明) | 读系统电网电压(按相) |
parallel_read_system_grid_power | 全局(声明) | 读系统电网功率(按相/全相求和) |
parallel_read_system_inv_power | 全局(声明) | 读系统逆变功率(按相/全相求和) |
parallel_read_system_backup_power | 全局(声明) | 读系统备电功率(按相/全相求和) |
parallel_read_system_inv_grid_freq | 全局(声明) | 读系统电网频率(取首个 ≥4000 的有效值) |
parallel_read_system_inv_backup_freq | 全局(声明) | 读系统备电频率 |
parallel_read_system_inv_pv_power | 全局(声明) | 读系统逆变侧 PV 总功率(4 路求和) |
parallel_read_system_inv_bat_curr | 全局(声明) | 读系统逆变侧电池电流(求和) |
parallel_read_system_inv_bat_power | 全局(声明) | 读系统逆变侧电池功率(求和) |
parallel_read_system_bat_rated_charge_power | 全局(声明) | 读系统电池最大充电功率(求和) |
parallel_read_system_bat_rated_dischg_power | 全局(声明) | 读系统电池最大放电功率(求和) |
parallel_read_system_bat_low_soc | 全局(声明) | 读系统最低 SOC |
parallel_read_system_bat_average_soc | 全局(声明) | 读系统平均 SOC |
parallel_read_system_bat_volt | 全局(声明) | 读系统电池电压(取首个正常机) |
parallel_read_system_bat_power | 全局(声明) | 读系统电池总功率(求和) |
parallel_read_system_cmd_force_charge_flag | 全局(声明) | 读"调度下令强制充电"标志(带清除副作用) |
parallel_read_system_sys_force_charge_flag | 全局(声明) | 读"系统预留 SOC 强充"标志(或逻辑) |
parallel_read_system_user_force_charge_flag | 全局(声明) | 读"用户强充"标志(带清除副作用) |
parallel_read_system_bat_force_charge_flag | 全局(声明) | 读"BMS 强制充电"标志(或逻辑) |
parallel_read_system_max_charge_power_limit | 全局(声明) | 读系统最大充电功率限值(求和) |
parallel_read_system_max_dischg_power_limit | 全局(声明) | 读系统最大放电功率限值(求和) |
parallel_read_system_self_test_flag | 全局(声明) | 读/驱动 150 s 自检状态机 |
parallel_read_gc_control_en | 全局(声明) | 读油机(generator)使能,下发给第三方逆变器 |
parallel_read_freq_dispatch_en | 全局(声明) | 读调频调度使能 |
parallel_read_dc_total_set_bat_power | 全局(声明) | 读 DC 侧电池总设定功率 |
parallel_read_dc_total_set_inv_power | 全局(声明) | 读 DC 侧逆变总设定功率 |
parallel_read_dc_total_set_grid_power | 全局(声明) | 读 DC 侧电网总设定功率 |
parallel_read_dc_three_phase_set_bat_power | 全局(声明) | 读 DC 侧三相电池设定功率 |
parallel_read_dc_three_phase_set_inv_power | 全局(声明) | 读 DC 侧三相逆变设定功率(按相) |
parallel_read_ac_total_set_inv_power | 全局(声明) | 读 AC 侧逆变总设定功率 |
parallel_read_ac_total_set_bat_charge_limit_power | 全局(声明) | 读 AC 侧电池总充电限值 |
parallel_read_ac_total_set_bat_dischg_limit_power | 全局(声明) | 读 AC 侧电池总放电限值 |
parallel_read_ac_total_set_bat_forced_charge_en | 全局(声明) | 读 AC 侧电池强制充电使能 |
parallel_read_ac_three_phase_set_inv_power | 全局(声明) | 读 AC 侧三相逆变设定功率(按相) |
parallel_read_ac_three_phase_set_bat_charge_limit_power | 全局(声明) | 读 AC 侧三相电池充电限值 |
parallel_read_ac_three_phase_set_bat_dischg_limit_power | 全局(声明) | 读 AC 侧三相电池放电限值 |
parallel_read_ac_three_phase_set_bat_forced_charge_en | 全局(声明) | 读 AC 侧三相电池强制充电使能 |
parallel_read_system_compensation_power | 全局(声明) | 读电表补偿功率 |
parallel_read_backup_en | 全局(声明) | 读备电使能 |
parallel_set_backup_en | 全局(声明) | 写备电使能 |
parallel_set_config_machine_precept | 全局(声明) | 写并机通信方案并触发配置保存 |
parallel_read_config_machine_precept | 全局(声明) | 读并机通信方案 |
parallel_read_inv_on_off | 全局(声明) | 无对应实现(全工程仅有此声明,见第 7 节) |
parallel_set_inv_on_off | 全局(声明) | 无对应实现(同上) |
parallel_set_full_power_priority_enable | 全局(声明) | 写满功率优先使能 |
parallel_read_full_power_priority_enable | 全局(声明) | 读满功率优先使能 |
parallel_set_bat_soc_threshold | 全局(声明) | 写满功率优先 SOC 门限 |
parallel_read_bat_soc_threshold | 全局(声明) | 读满功率优先 SOC 门限 |
4. 核心逻辑解析
本文件无执行逻辑,本节说明它定义的内存布局与协议映射约定,这是理解 CAN/SCI 两个通信实现的前提。
4.1 #pragma pack(1) 的强约束
第 24 行 #pragma pack(1) 覆盖到第 261 行 #pragma pack()。所有并机结构体都是逐字节紧排、无对齐填充。这意味着:
PARALLEL_HOST_MACHINE_NETWORKING_PARAMETER_T的前 5 字节恰好是u8_unique_device_id[2] + u8_mac[3],因此在parallel_can.c:103、parallel_can.c:548、parallel_sci.c:88中可以直接用memcmp(rxMsg->frame_data, &g_t_host_machine_networking_info[i], 5)与收到的报文前 5 字节比对——这是"用结构体首地址当报文头"的写法,依赖 pack(1) 且依赖这 5 个字段排在最前。PARALLEL_FROM_MACHINE_NETWORKING_PARAMETER_T同理,parallel_can.c:548用它做从机身份校验。
4.2 地址空间约定
- 数组下标即"并机地址":
g_t_host_machine_*_info[0]恒为本机(主机自身数据),[1]…[15]为从机。索引 0 被大量函数硬编码为"本机"(如所有parallel_read_*从[0]取值)。 g_t_host_machine_networking_info[i].u8_parallel_addr_en是"该槽位已被占用且在线"的唯一判据;u8_parallel_lost_flag是"通信丢失"判据。二者的组合由parallel.c:310 parallel_machine_isWorkInNormalMode()封装为"该机在线且工作于cNormalMode"。
4.3 主机/从机双结构的对称关系
- 主机的"发送段"字段(
PARALLEL_HOST_MACHINE_RUNNING_INFO_T第 105-138 行)与从机的"接收段"字段(PARALLEL_FROM_MACHINE_RUNNING_INFO_T第 223-256 行)字段集合完全一致、顺序一致。这是全部通信层逐字段赋值能"对得上"的根本原因:CAN 侧parallel_can.c:211-326(主机发)与parallel_can.c:793-849(从机收)、SCI 侧parallel_sci.c:357-419(主机发)与parallel_sci.c:729-862(从机收)都按这个顺序一一对应。 - 同理,主机"接收段"(逆变器规格/运行数据 + 电池数据)与从机在
parallel_can.c:593-761组帧时用的g_t_host_machine_running_info[0]字段一一对应。
4.4 SOC 与功率的单位约定
从所有使用点反推(parallel.c:71-76 的 logic_read_*_soc()*10、parallel.c:130 注释"小于预留值-1 给电池充电"、parallel.c:383 的 u16_bat_soc < threshold*10):
u16_bat_soc单位为 0.1%(1000 = 100%)。- 各
s16_*_power单位为 0.1 kW(与工程内其它逆变器接口一致)。 - 因此
parallel.c中大量的+4/-4/-10分别是 0.4% / 0.4% / 1% 的迟滞量。
4.5 定时/自适应时序常量
PARALLEL_MSTER_CHECK_TIME/PARALLEL_SLAVE_CHECK_TIME只在midware/interface/interface.c:262使用:当并机通信方案尚未确定(u8_parallel_precept == PARA_COM_TYPE_NONE)且无通信成功时,按主机/从机角色分别以 15 s / 30 s 为周期在 CAN ↔ UART4 ↔ USART3 之间轮换尝试,直到某一方案收到帧(u8_comm_success_flag置位),随后把选中的方案写入u8_parallel_precept持久化。
5. 对外接口
5.1 本文件导出
- 类型:
PARALLEL_MODE_E、PARALLEL_COM_TYPE_E、PARALLEL_COM_CARD_STATUS_E、BAT_WORK_FLAG_U、UPGRADE_FLAG_U、PARALLEL_TOTAL_MACHINE_NETWORKING_T、PARALLEL_HOST_MACHINE_NETWORKING_PARAMETER_T、PARALLEL_FROM_MACHINE_NETWORKING_PARAMETER_T、PARALLEL_HOST_MACHINE_RUNNING_INFO_T、PARALLEL_FROM_MACHINE_RUNNING_INFO_T。 - 常量:
PARALLEL_MAX_NUM等 6 个宏。 - 全局变量:
g_t_parallel_total_machine_network(唯一)。 - 函数声明:见第 3 节完整清单。
- 主要调用方:
midware/inverter/parallel.c(实现并机业务)、parallel_comm/parallel_can.c、parallel_comm/parallel_sci.c(通信实现)、midware/interface/interface.c(通信方案自适应 + PV 充电器)、midware/auxiliary/system_aux.c、logic/logic.c、logic/ac_control.c、logic/dispatch.c、data/resume_data/flash/flash_data_store.c、net/ems.c、net/server.c、midware/inverter/alphaess/*、midware/inverter/ginlong/*、midware/inverter/inovance/*、midware/inverter/goodwe/*、midware/interface/modbus/*。
5.2 本文件依赖
#include "chip.h"——工程统一的基础类型头(u8/u16/s16/s32/TRUE/FALSE)。
5.3 未在头文件中导出但实际跨文件使用的全局变量
以下 4 个全局变量定义在 parallel.c:36-40,但没有在本头文件声明,而是由 parallel_can.c:22-26 和 parallel_sci.c:29-33 各自用 extern 重复声明:
g_t_host_machine_networking_info[PARALLEL_MAX_NUM]g_t_host_machine_running_info[PARALLEL_MAX_NUM]g_t_from_machine_networking_infog_t_from_machine_running_info
net/ems.c:128 也单独 extern 了 g_t_host_machine_running_info。
6. 依赖关系
- 依赖:
chip.h(基础类型)。无其它模块依赖。 - 被依赖:
midware/inverter/parallel.c(实现本文件声明的绝大部分函数)midware/inverter/parallel_comm/parallel_can.h/parallel_sci.h(这两个头文件都#include "chip.h",但其.c会同时包含parallel.h)midware/interface/interface.c、midware/interface/modbus/modbus.c、midware/interface/modbus/sunspec_business.cmidware/auxiliary/system_aux.clogic/logic.c、logic/ac_control.c、logic/dispatch.cdata/resume_data/flash/flash_data_store.cnet/ems.c、net/server.c- 各逆变器厂商通信层:
alphaess_comm_can.c、alphaess_comm_usart.c、ginlong_comm_can.c、ginlong_comm_usart.c、inovance_comm_can.c、inovance_comm_usart.c、goodwe_comm.c
7. 备注与风险点
- 头文件声明与实现不一致(死声明):
parallel_read_inv_on_off(第 331 行)和parallel_set_inv_on_off(第 332 行)在parallel.c中没有实现,全工程也没有任何调用点(已全仓 grep 确认)。属于版本遗留声明,应删除或补实现。
PARALLEL_BAT_LIMT_CTRL_RATE_SET未被使用:该宏(第 22 行)在头文件里定义了"按功率上限占比分配的权重 = 1",但parallel.c的功率分配公式用的是硬编码/2和/10(见parallel.c:447-471),宏从未被引用,属于设计意图与实现脱节的遗留。
- 4 个核心全局变量未在此头文件导出:
g_t_host_machine_networking_info等由各.c各自extern,任何字段/类型变更都需要同步修改多处extern声明,容易出现类型不一致(编译器无法跨extern校验结构体一致性)。
- 结构体全量按字段映射通信:因为
#pragma pack(1)+ 字段顺序即协议顺序,任何在PARALLEL_HOST_MACHINE_RUNNING_INFO_T中间插入/删除字段都会静默改变 CAN/SCI 的寄存器与字节序映射,导致主从机版本不匹配——升级时这是高危点,且无任何版本号或 CRC 保护该类结构。
BAT_WORK_FLAG_U/UPGRADE_FLAG_U的位域宽度为 2 bit 而非 1 bit:bit_bms_comm_flag:2等,取值 0-3,但使用方一律按FALSE/TRUE(0/1)判断,!= FALSE比较对非 0 值成立,语义上"2、3"这类未定义值会被当成真。属于可容忍但语义不清晰的写法。
- 头文件不含 include guard 之外的自包含保护:
parallel.h依赖chip.h提供u8/s16/s32/TRUE/FALSE,但不依赖PARALLEL_*_E之外的第三方类型,这一点是干净的;不过PARALLEL_TOTAL_MACHINE_NETWORKING_T等结构体在#pragma pack(1)区间内定义,若其它头文件在包含顺序上把parallel.h放入带对齐属性的上下文中(当前工程没有),会产生布局偏差。
PARALLEL_MODE_E与t_config_data.u8_parallel_mode的语义重叠:枚举里是"从机=0/主机=1/其它",而实际配置字段inverter.h:474 u8_parallel_mode注释也是"0 从机 1 主机",二者数值一致但PARALLEL_MODE_E在工程内几乎不被直接使用(parallel.c只用了OTHER_MACHINE作静态初值),属于冗余定义。