ginlong_comm_usart.h
GINLONG_COMM_INFO_T)的设计4.4 单位与精度约定4.5 与 uCOS-II 的配合5. 对外接口6. 依赖关系7. 备注与风险点源文件路径:
midware/inverter/ginlong/ginlong_comm_usart.h所属模块:midware / inverter / ginlong(锦浪(Solis)逆变器 Modbus-RTU 通信) 代码行数:935
1. 文件职责
本文件是 EMS 与锦浪(Ginlong/Solis)储能逆变器 Modbus-RTU 串口主通道 的对外契约与数据定义中心。它把逆变器侧全部需要用到的 Modbus 寄存器地址、功能码、型号子码、国家安规码、故障位域、运行/配置参数结构体集中定义,并通过 extern GINLONG_TABLE_T g_t_ginlong_info 向整个工程暴露唯一的一份"锦浪通道状态表"。
实现体全部在 ginlong_comm_usart.c 中;本文件只提供类型、宏和 4 个函数原型。数据流位置:inverter.c 的逆变器轮询任务调用 ginlong_inverter_comm() → 该实现按寄存器表收发 → 结果写入 g_t_inv_info(对外统一运行数据)与 g_t_ginlong_info(锦浪私有缓存/标志位)→ 上层调度与显示读取。
g_t_ginlong_info 中的 t_ginlong_comm_info 是一张巨大的"待办标志位表"(约 50 个 u8/u16 命令与查询请求标志),实现了上层(HMI、服务器、并机、BMS)与本文件的异步解耦:上层只置标志,本文件在轮询里消费标志并发帧。
2. 关键数据结构与宏
2.1 宏常量
| 名称 | 类型 | 说明 |
|---|---|---|
GL_VERSION_INVHARD / GL_VERSION_INVHARD_V2 | 宏 | "V1.01" / "V1.02",逆变器硬件版本字符串,用于型号识别与校验 |
TIME_100MS / TIME_1S | 宏 | 100 / 1000,节拍换算常量 |
GINLONG_T10_SUB | 宏 | 0xBF,33000 寄存器返回的 T10 机型子码(V1) |
GINLONG_T10_SUB_V2 | 宏 | 0xF0,T10 机型子码(V2 硬件) |
GINLONG_S3_6_SUB / GINLONG_S4_6_SUB | 宏 | 0x3135 / 0x3136,S3.6 / S4.6 机型子码 |
GINLONG_S5_SUB / GINLONG_S5_SUB_V2 | 宏 | 0x3133 / 0x3137,S5 机型子码(两代硬件) |
GINLONG_S6_SUB | 宏 | 0x3138,S6 机型子码 |
GINLONG_B5_SUB | 宏 | 0x4132,B5 机型子码 |
GINLONG_INV_DEBUG | 宏 | 调试打印总开关,默认 0 |
GINLONG_MAX_REGISTER_NUM | 宏 | 100,单次多寄存器写允许的最大寄存器数(组帧时做上界校验) |
GINLONG_INV_RECV_BUFFER_SIZE | 宏 | 256,接收缓冲 g_u8_inv_recv_buf 的长度 |
GINLONG_DAT_PCK_INTERVAL_INV | 宏 | 700 ms,两条 Modbus 报文之间的最小间隔,也是收帧等待超时 |
GINLONG_SLAVE_ADDRESS | 宏 | 1,Modbus 从机地址(逆变器) |
GINLONG_FUNC_READ_HOLDING_REGISTER | 宏 | 0x03,读保持寄存器 |
GINLONG_FUNC_READ_INPUT_REGISTER | 宏 | 0x04,读输入寄存器(只读运行数据) |
GINLONG_FUNC_WRITE_SIGNAL_HOLDING_REGISTER | 宏 | 0x06,写单个保持寄存器 |
GINLONG_FUNC_WRITE_MULTIPLE_HOLDING_REGISTER | 宏 | 0x10,写多个保持寄存器 |
输入寄存器地址宏(3xxxx,只读取)
| 名称 | 值 | 说明 |
|---|---|---|
ADDR_REGISTER_PRODUCT_MODEL / NUM_INV_PRODUCT_MODEL | 33000 / 20 | 产品型号、软/硬件版本、SN |
ADDR_PV_ENERGY_STATISTICS / NUM_PV_ENERGY_STATISTICS | 33029 / 2 | PV 发电量统计 |
ADDR_REGISTER_QUERY_SAFETY_TEST_DATA / NUM_QUERY_SAFETY_TEST_DATA | 33221 / 22 | 安规自检数据区 |
ADDR_REGISTER_QUERY_ITALY_TEST_DATA_1 / NUM_QUERY_ITALY_TEST_DATA_1 | 33223 / 20 | 意大利自检 L1 相数据 |
ADDR_REGISTER_RUNDATA_1 / NUM_RUNDATA_1 | 33029 / 93 | 运行数据块 1(33029–33121) |
ADDR_REGISTER_RUNDATA_2 / NUM_RUNDATA_2 | 33132 / 81 | 运行数据块 2(33132–33212) |
ADDR_ITALY_SELF_INSPECTION_RESULTS / NUM_ITALY_SELF_INSPECTION_RESULTS | 33334 / 3 | 意大利自检三相结论 |
ADDR_REGISTER_QUERY_ITALY_TEST_DATA_2 / NUM_QUERY_ITALY_TEST_DATA_2 | 33470 / 40 | 意大利自检 L2/L3 相数据 |
保持寄存器地址宏(4xxxx,可读可写)
| 名称 | 值 | 说明 |
|---|---|---|
ADDR_SET_INV_RTC_TIME / NUM_SET_INV_RTC_TIME | 43000 / 6 | 逆变器 RTC 时间(年/月/日/时/分/秒) |
ADDR_INV_ON_OFF_COMMAND / NUM_INV_ON_OFF_COMMAND | 43007 / 1 | 开关机命令(0xBE 开 / 0xDE 关) |
ADDR_REGISTER_SET_AC_POWER / NUM_SET_AC_POWER | 43052 / 1 | AC 有功功率设定 |
ADDR_SET_WORK_MODE / NUM_SET_WORK_MODE | 43050 / 5 | 并网工作模式(工作模式/无功/有功/功率因数等) |
ADDR_SAFETY_REGULATIONS_INFO / NUM_SAFETY_REGULATIONS_INFO | 43050 / 60 | 安规参数读取区(43050–43109) |
ADDR_CLEAN_ENERGY_STATISTICS / NUM_CLEAN_ENERGY_STATISTICS | 43055 / 1 | 清除能量统计 |
ADDR_SET_SAFETY / NUM_SET_SAFETY | 43068 / 1 | 设置安规国家码 |
ADDR_SET_ITALY_SELF_INSPECTION / NUM_SET_ITALY_SELF_INSPECTION | 43079 / 1 | 意大利一键自检使能 |
ADDR_FAULT_RECOVER_PROTECT_VALUE / NUM_FAULT_RECOVER_PROTECT_VALUE | 43082 / 8 | 故障恢复后上限电压/频率 + 首次开机上下限(43082–43089) |
ADDR_OVP_UPV_VALUE / NUM_OVP_UPV_VALUE | 43090 / 8 | 一/二级过欠压保护点及时间 |
ADDR_OFP_UFP_VALUE / NUM_OFP_UFP_VALUE | 43098 / 8 | 一/二级过欠频保护点及时间 |
ADDR_WAIT_AND_RECONNECT_TIME_VALUE / NUM_WAIT_AND_RECONNECT_TIME_VALUE | 43106 / 2 | 上电启动时间、故障恢复时间 |
ADDR_10MIN_OVP_TIME_VALUE / NUM_10MIN_OVP_TIME_VALUE | 43108 / 2 | 十分钟过压保护点与时间 |
ADDR_REGISTER_BMS_PROTECT_PARAMETER / NUM_BMS_PROTECT_PARAMETER / NUM_BMS_PROTECT_PARAMETER2 | 43111 / 15 / 12 | 电池保护参数区(T10 用 15 个寄存器,S 系列用 12 个) |
ADDR_CONTROL_BACKUP_BAT_ENABLE / NUM_CONTROL_BACKUP_BAT_ENABLE | 43111 / 4 | backup 输出使能 + 电压/频率设定 |
ADDR_SEND_BAT_PROTECT_PARAMETER / NUM_SEND_BAT_PROTECT_PARAMETER | 43117 / 6 | 电池保护参数(续) |
ADDR_SEND_BAT_OVERLTAGE_PROTECT / NUM_SEND_BAT_OVERLTAGE_PROTECT | 43122 / 1 | 电池过压保护 |
ADDR_CONTROL_THREE_UNBALANCE_MODE / NUM_CONTROL_THREE_UNBALANCE_MODE | 43191 / 1 | 三相不平衡功能使能 |
ADDR_CONTROL_THREE_UNBALANCE_POWER / NUM_CONTROL_THREE_UNBALANCE_POWER | 43192 / 3 | 三相不平衡每相功率(当前未使用,见 ginlong_comm_usart.c:4158 注释块) |
ADDR_INV_PU_MODE_V1_SET / NUM_INV_SAFETY_MODE_SET1 / NUM_INV_PU_MODE_V1_SET | 43200 / 21 / 50 | PU/QU 曲线参数区(写 21 个寄存器的子集,读全 50 个) |
ADDR_INV_PU_V3_VALUE / ADDR_INV_PU_V4_VALUE | 43202 / 43203 | P(U) 模式 V3/V4 电压点 |
ADDR_INV_QU_V1_VALUE ~ ADDR_INV_QU_V4_VALUE | 43208~43211 | Q(U) 模式 V1–V4 电压点 |
ADDR_INV_POWER_CHANGE_SLOPE_LIMIT / NUM_INV_POWER_CHANGE_SLOPE_LIMIT | 43222 / 1 | 功率变化斜率限制 |
ADDR_INV_FREQ_LOAD_SHED_MODE / NUM_INV_FREQ_LOAD_SHED_MODE | 43226 / 1 | 频率减载模式 |
ADDR_FREQ_DERATING_PROTECT_VALUE / NUM_FREQ_DERATING_PROTECT_VALUE | 43227 / 1 | 过频减载起始频率 |
ADDR_FREQ_DERATING_PROTECT_RATE_VALUE / NUM_FREQ_DERATING_PROTECT_RATE_VALUE | 43228 / 1 | 过频减载斜率 |
ADDR_INV_GFCI_PROTECT_VALUE / NUM_INV_GFCI_PROTECT_VALUE | 43245 / 3 | 漏电流保护限值 |
ADDR_INV_ISOLATION_LIMIT_VALUE / NUM_INV_ISOLATION_LIMIT_VALUE | 43246 / 1 | 绝缘阻抗保护限值 |
ADDR_INV_SPECIAL_SETTING_IGFOLLOW / NUM_INV_SPECIAL_SETTING_IGFOLLOW | 43249 / 1 | 特殊设置:电网追踪(igfollow)等 |
ADDR_INV_SPECIAL_SETTING_MPPT_SWITCH / NUM_INV_SPECIAL_SETTING_MPPT_SWITCH | 43302 / 1 | MPPT 开关 / 阴影扫描 / 奥地利 bit0 |
ADDR_INV_CLEAN_OVERLOAD_FLAG / NUM_INV_CLEAN_OVERLOAD_FLAG | 43312 / 1 | 清除过载标志 |
ADDR_INV_LOW_VOLTAGE_CROSS / NUM_INV_LOW_VOLTAGE_CROSS | 43330 / 1 | 低压穿越 / FRT 使能 |
ADDR_INV_PU_MODE_ACTIVE_RESPONSE_3TAU / NUM_INV_PU_MODE_ACTIVE_RESPONSE_3TAU | 43403 / 1 | P(U) 有功响应时间常数 3Tau |
ADDR_INV_ZERO_CURRENT_VOLTAGE / NUM_INV_ZERO_CURRENT_VOLTAGE | 43443 / 1 | 零电流模式电压 |
2.2 枚举
| 名称 | 类型 | 说明 |
|---|---|---|
ON_OFF_E | 枚举 | OFF=0 / ON,通用开关 |
GINLONG_SPECIAL_SETTING_E | 枚举 | SPECIAL_SETTING_NONE / IGFOLLOWE_FLAG / FRT_ENABLE_FLAG,标记本次要改哪一项特殊设置(与 u8_set_special_setting_flag 配合) |
MPPT_SWITCH_CTRL_E | 枚举 | MPPT_SWITCH_ON_DEFAULT=0 / MPPT_SWITCH_STOP,对应 43302 bit9 |
SAFETY_RESPONSE_MODE | 枚举 | NO_RESPONSE_IDLE / ACTPOWER_RESPONSE / REACPOWER_RESPONSE,set_inv_grid_parameter_tuning() 安规调参状态机状态 |
GINLONG_WORK_MODE_E | 枚举 | NO_RESPONSE_MODE / VOLT_WATT_DEFAULT / VOLT_VAR / FIXED_POWER_FACTOR / FIX_REACTIVE_POWER / POWER_PF / WORK_MODE_MAX,43050 工作模式取值 |
SAFETY_E | 枚举 | STD_SAFETY / GINLONG_SAFETY / STANDARD_SAFETY / GINLONG_SAFETYSUB / STANDARD_SAFETYSUB / MAX_SAFETY,exchange_safety() / exchange_safetysub() 的转换方向选择 |
FREQ_LOAD_SHED_MODE_E | 枚举 | 频率减载/国家需求码,NO_REQUIRE、AUSTRALIA_REQUIRE、G98_AND_G99_REQUIRE、BDEW_REQUIRE、ITALY_REQUIRE…(含 SOUTH_AFRICA_LEVELISE_REQUIRE = 0x10) |
GINLONG_H_NATIONAL_STANDARD_E | 枚举 | T10 高压机型(3 相 230/400V 级)国家安规码表,约 100 项,值 0x00–0x70 且 GL_H_PPDS = 0xA2 |
GINLONG_L_NATIONAL_STANDARD_E | 枚举 | S 系列低压机型(单/三相 230V 级)国家安规码表,约 90 项,值 0x00–0x61 |
2.3 位域联合体(逆变器故障/状态字)
均为 union { u16 u16_all; struct { u8 b0..b15 : 1; } bit; } 形式,可用 u16_all 整体判零、也可逐位读:
| 名称 | 类型 | 说明 |
|---|---|---|
GINLONG_ONGRID_FAULT_STATUS_U | 联合体 | 并网侧故障:电网过/欠压、过/欠频、三相不平衡、频率抖动、过流、电流跟踪故障、电表故障等(对应 33116) |
GINLONG_BACKUP_FAULT_STATUS_U | 联合体 | Backup 侧故障:u8_backup_ovp、u8_backup_overload、u8_grid_backup_overload,其余保留(对应 33117) |
GINLONG_INV_FAULT1_STATUS_U | 联合体 | 逆变器故障 1:直流过压、母线过/欠压/不平衡、A/B 路过流、IGBT 过流、AFCI、电弧、电网电流采样异常、DSP 自检、电池放电 OCP(对应 33119) |
GINLONG_INV_FAULT2_STATUS_U | 联合体 | 逆变器故障 2:电网扰动、直流注入、过温、继电器自检、欠温、PV 绝缘、12V 欠压、GFCI、DSP-B、LLC 硬件、电池过压硬件、CAN/DSP 丢失(对应 33120) |
GINLONG_SPECIAL_FUNC_CONTROL_U | 联合体 | 43302 特殊功能控制字:u8_boost_control、u8_dc_component_control、u8_afci_self_check、u8_mppt_enable(bit9)等 |
GINLONG_SPECIAL_SEETING_U | 联合体 | 43249 特殊设置字:u8_mppt_parallel、u8_igfollow、u8_realy_fault_func、u8_ileak_fault_func、u8_pv_g_fault_func、u8_grid_intf02_func、u8_igad_check_pro、u8_consrt_voltage、u8_grid_filt_level:4、u8_afci_pro_level:4 |
ITALY_SAFTY_TEST_RESULT_U | 联合体 | 意大利自检单项结果位:u8_result_true_or_false、过压 10min 值/时间、过压值/时间、欠压值/时间…(注意结构体末尾多出一个 u8_test_ufp2_time_result:1 重复成员,见备注) |
2.4 结构体
| 名称 | 类型 | 说明 |
|---|---|---|
GINLONG_SAFETY_INFO_T | 结构体 | 安规全量参数缓存(约 80 个 u16):AFCI/意大利自检开关、故障恢复点、一/二/三级过欠压(值+时间)、10 分钟过压、一/二/三级过欠频、启动/重连时间、P(U) 与 Q(U) 曲线各 4 点、功率斜率、频率减载参数 1–6、欠频升载起点与斜率、GFCI/绝缘/LVRT 限值、特殊设置字、工作模式与有功/无功/功率因数设定、零电流电压、u_italy_test_res[3] 与一键全检使能值 |
GINLONG_CONTROL_TABLE_T | 结构体 | 控制项少量状态:u8_backup_set(backup 期望状态)、u8_charge_limit_enable(限充)、u16_set_power_change_slope_limit_value、意大利一键全检的"下发/查询"两个使能位 |
GINLONG_RUNDATA_TABLE_T | 结构体 | 从逆变器读回并缓存的运行态:子机型 u8_inv_model_sub、硬件版本 u8_hw_ver[10]、backup 状态、功率因数、电池使能设定、频率减载模式、低压穿越模式、43302 控制字、绝缘限值、特殊设置字、锦浪安规码、零电流标志、4 个故障联合体、阴影扫描使能、系统状态 |
GINLONG_COMM_INFO_T | 结构体 | 本文件的调度核心:u8_ems_inv_comm_flag(通道是否已建立)、u32_ems_inv_comm_tick(最后一次成功通信节拍,用于 30 s 失联判断)以及约 50 个"请求标志"(置 TRUE 触发一次读/写,完成后清 FALSE)+ 若干节拍字段 |
GINLONG_DEBUG_TABLE_T | 结构体 | 仅含 s32_ginlong_debug_1(33205 相关调试量,当前赋值代码已注释) |
GINLONG_TABLE_T | 结构体 | 顶层聚合:t_ginlong_comm_info + t_ginlong_rundata + t_control_cmd + t_ginlong_debug + t_ginlong_safety_info |
2.5 导出的全局变量
| 名称 | 类型 | 说明 |
|---|---|---|
g_t_ginlong_info | GINLONG_TABLE_T | 唯一实例,在 ginlong_comm_usart.c:31 定义;inverter.c、ginlong_comm_can.c 直接读写 |
3. 函数清单
本文件为头文件,不含函数实现,仅声明 4 个函数原型(ginlong_comm_usart.h:930-933):
| 函数名 | 作用域 | 说明 |
|---|---|---|
ginlong_comm_init | 全局(声明) | 锦浪串口通道初始化:复位初始标志位、默认开机、backup 使能、MPPT 100% |
ginlong_inverter_comm | 全局(声明) | 串口通道周期主函数:升级分支 + 失联检测 + 约 50 个标志位分派的读/写调度 |
ginlong_inverter_data_check | 全局(声明) | 数据一致性检查与"防超额"限幅:把 BMS/配置限值折算为逆变器可写的电池保护参数,并派生 backup、重启、清过载等标志 |
ginlong_get_self_test_data | 全局(声明) | 获取意大利安规自检数据并汇总成三相自检结果 |
说明:
.c中还有约 60 个非static函数(如set_safety、set_inv_ac_actpower、query_inv_product_model等)未在本头文件中声明,它们由ginlong_comm_usart.c自身调用或经inverter.h间接暴露,属于头文件声明不完整的遗留问题(详见第 7 节)。
4. 核心逻辑解析
本文件是纯声明文件,不含控制流,但其中的常量取值与结构体布局本身就是协议契约,解析如下:
4.1 Modbus-RTU 帧格式约定
本文件定义的功能码与寄存器地址直接决定 .c 的组帧方式:
- 读请求(
0x03/0x04)8 字节:[从机地址][功能码][起始地址高][起始地址低][数量高][数量低][CRC低][CRC高] - 写单寄存器(
0x06)8 字节:[从机地址][0x06][地址高][地址低][数据高][数据低][CRC低][CRC高] - 写多寄存器(
0x10)7+2N+2 字节:[从机地址][0x10][地址高][地址低][数量高][数量低][字节数=2N][数据…][CRC低][CRC高] - CRC 为 Modbus 标准 CRC16,低字节在前(构造见
ginlong_comm_usart.c:327-328) GINLONG_MAX_REGISTER_NUM = 100是单次写多寄存器的硬上界,ems_send_ctrl_data_to_ginlong()会用它做参数校验,因此本文件中所有NUM_*宏都不允许超过 100。
4.2 两类机型与两套安规码表
GINLONG_H_NATIONAL_STANDARD_E 与 GINLONG_L_NATIONAL_STANDARD_E 是同一批安规在不同硬件代次上的两套编码:H 表用于 T10(高压三相机型,SUB_T10),L 表用于 S5/B5/S3.6/S4.6/S6(低压机型)。两表的编码值并不一一对应(例如 H 表 GL_H_AS4777_A = 0x64,L 表 GL_L_AS4777_A = 0x55),因此 .c 中必须有 exchange_safety() / exchange_safetysub() 两张转换表,用 SAFETY_E 枚举的 GINLONG_SAFETY(逆变器→EMS)与 STANDARD_SAFETY(EMS→逆变器)区分方向。
4.3 命令标志位表(GINLONG_COMM_INFO_T)的设计
该结构体是本文件最重要的接口设计,其约定为:
| 类别 | 字段示例 | 语义 |
|---|---|---|
| 一次性写请求 | u8_set_safety_flag、u8_clean_energy_flag、u8_restart_inv_flag、u8_set_pu_v3_flag … | 上层置 TRUE → .c 在轮询中执行一次写 → 收到正确应答后清 FALSE |
| 一次性读请求 | u8_query_safety_config_flag、u8_query_freq_load_shed_mode_flag、u8_query_pu_3tau_flag … | 同上,但执行的是读 |
| 周期节拍 | u32_query_run_data_1_tick、u32_query_run_data_2_tick、u32_query_bat_protect_parameter_tick、u32_send_bms_protect_parameter_to_inv_tick | .c 内部按 OSTimeGet() 差值与阈值比较,周期触发 |
| 握手/链路 | u8_ems_inv_comm_flag、u32_ems_inv_comm_tick | 型号识别成功→flag = TRUE;每收到任一合法应答→刷新 tick;tick 超 30 s 未刷新视为失联 |
| 互斥闸门 | u8_allow_pu_set_flag、u8_allow_qu_set_flag | 由安规调参状态机(SAFETY_RESPONSE_MODE)逐级放开,避免在错误工作模式下写 PU/QU 曲线 |
"置位—消费—复位"是唯一同步机制,没有信号量或邮箱保护;因此所有置位方必须与 .c 运行在同一任务上下文(实际都在 inverter.c 的逆变器任务里),否则存在竞态。
4.4 单位与精度约定
本文件注释给出了逆变器侧与 EMS 侧的单位换算关系,.c 的乘除系数全部来源于此:
| 物理量 | 逆变器侧 | EMS 侧 |
|---|---|---|
| 电压 | 0.1 V | 0.1 V(部分点位经 exchange_* 后按 *10/23 折算) |
| 频率 | 0.01 Hz | 0.01 Hz |
| 保护时间 | 0.01 s | 0.01 s(部分点位在 .c 中被 /10) |
| 功率百分比 | 0.01 % | 0.01 % |
| 功率因数 | 0.001 | 0.01(.c 中 /10 转换) |
| P(U)/Q(U) 曲线电压 | 寄存器原值 | *10/23(T10 的 230V 基准折算,见 ginlong_comm_usart.c:2131-2140) |
4.5 与 uCOS-II 的配合
本文件不涉及任务、信号量或邮箱,但结构体中的 u32_*_tick 字段全部以 OSTimeGet() 的系统节拍(ms)为基准,并依赖 .c 中的回绕兜底逻辑(if (tick > OSTimeGet()) tick = OSTimeGet();)。
5. 对外接口
本文件导出(供外部调用):
| 符号 | 类型 | 调用方 |
|---|---|---|
ginlong_comm_init | 函数声明 | midware/inverter/inverter.c:82(inverter_state_init()) |
ginlong_inverter_comm | 函数声明 | midware/inverter/inverter.c:1105(逆变器轮询任务) |
ginlong_inverter_data_check | 函数声明 | midware/inverter/inverter.c:1106 |
ginlong_get_self_test_data | 函数声明 | midware/inverter/inverter.c:314(italian_self_test_handle()) |
g_t_ginlong_info | 全局变量 | midware/inverter/inverter.c(约 60 处置位/读取)、midware/inverter/ginlong/ginlong_comm_can.c:302 |
全部寄存器地址宏、NUM_* 宏 | 宏 | ginlong_comm_usart.c、ginlong_upgrade.c |
| 全部机型子码宏、安规码枚举 | 宏/枚举 | ginlong_comm_usart.c 的 exchange_safety() / query_inv_product_model() |
| 故障位域联合体 | 联合体 | ginlong_comm_usart.c 的 deal_inv_fault() |
本文件调用的外部接口:
| 名称 | 来源 |
|---|---|
includes.h | 工程总头文件(u8/u16/u32/s8/s16/s32、TRUE/FALSE、OSTimeGet 等) |
ginlong_upgrade.h | 同目录升级模块(本文件 include 但未直接使用其符号) |
6. 依赖关系
依赖(include): includes.h(ginlong_comm_usart.h:13)、ginlong_upgrade.h(:14)。依赖极少,是设计良好的地方——头文件不引入其他业务头。
被依赖:
midware/inverter/ginlong/ginlong_comm_usart.c—— 唯一实现体。midware/inverter/ginlong/ginlong_comm_can.c—— 使用g_t_ginlong_info.t_ginlong_comm_info.u8_ems_inv_comm_flag判断串口通道是否已建立(ginlong_comm_can.c:302)。midware/inverter/ginlong/ginlong_comm_can.h—— 间接经由ginlong_comm_usart.h。midware/inverter/inverter.c—— 大量置位g_t_ginlong_info中的请求标志(约 60 处),并调用 4 个导出函数。user/EMS_3_0.uvprojx—— 编译单元注册。
7. 备注与风险点
- 文件头注释与实际文件名不符:
ginlong_comm_usart.h:2写的是@file :ginlong_comm.h,实际文件名已改为ginlong_comm_usart.h(推测是串口/CAN 双通道拆分时的遗留),版本仍标V1.0.0 / 2017/06/28,与实际内容(含 2023 年后新增的意大利自检、FRT、阴影扫描等)严重脱节。 - 头文件声明严重不完整:
.c中约 60 个非static函数(set_safety、set_inv_ac_actpower、query_inv_rundata_1/2、inv_on_off_command等)未在此声明。它们能被inverter.c调用,是因为inverter.h另有声明;但这导致本头文件不能独立反映模块接口,且漏掉了编译期原型检查(C89 下隐式声明会静默通过,一旦实参类型写错不会报错)。 ITALY_SAFTY_TEST_RESULT_U位域数目异常:ginlong_comm_usart.h:664-687的匿名结构体里,u8_test_ufp2_time_result出现了两次(:686与前面的:684重名,且总位数 17 位 >u16的 16 位)。重复成员名在 C 中是非法/未定义的,多出的第 17 位会被丢弃。该联合体在.c中只用u16_all(ginlong_comm_usart.c:3812-3814、:4006-4008),未访问bit域,所以目前不产生功能问题,但属于明显的复制粘贴缺陷。GINLONG_DEBUG_TABLE_T已是死代码:唯一成员s32_ginlong_debug_1的赋值代码在.c中已被注释(ginlong_comm_usart.c:1597-1604),结构体本身保留。NUM_FREQ_DERATING_PROTECT_VALUE被从 2 改成 1(:160-161保留了旧值注释),对应 43227/43228 只能单寄存器写(.c:3195注释"多寄存器写入写不进去"),说明逆变器固件行为变化后只在 EMS 侧打补丁,未更新协议文档。ADDR_REGISTER_RUNDATA_1与ADDR_PV_ENERGY_STATISTICS同为33029、ADDR_SET_WORK_MODE与ADDR_SAFETY_REGULATIONS_INFO同为43050、ADDR_REGISTER_BMS_PROTECT_PARAMETER与ADDR_CONTROL_BACKUP_BAT_ENABLE同为43111。这是同一寄存器区被不同功能复用的正常现象,但宏名容易误导,阅读.c时需按NUM_*长度判断实际读写范围。u8_inv_backup_status(GINLONG_RUNDATA_TABLE_T)语义反直觉:.c中存的是寄存器原值 + 1(ginlong_comm_usart.c:1583),因此0表示未读到、1/2才是BACKUP_*枚举值,与t_control_cmd.u8_backup_set的比较必须做-1处理,极易出错。GINLONG_COMM_INFO_T无任何并发保护:所有请求标志由上层(inverter.c)置位、由本模块消费,若将来有第二个任务写入(例如 HMI 任务直接改变配置并置标志),会出现"标志被同一轮消费两次"或"写请求丢失"。当前设计假设单任务,缺少注释说明这一约束。exchange_safety()对未知子机型返回 0:函数体只有SUB_T10与SUB_S5/B5/S3.6/S4.6/S6两个分支(ginlong_comm_usart.c:345、:545),其余sub值直接返回l_u16_safety = 0,即"未知安规码"。若新增机型而忘记在此处扩展,安规读取会静默变成 0 而不是报错。