evc_ii.h
源文件路径:
midware/evc/evc_ii.h所属模块:midware/evc(二代交流充电桩 SMILE-G3 系列通信中间件) 代码行数:390
1. 文件职责
本文件是二代充电桩(EVC-II,支持单相/三相、最多 4 桩并机)通信中间件的对外声明头文件,定义多桩配置表数组、多桩运行数据数组、故障位域及 13 个接口原型。
与一代 evc.h 的关键差异是从"单桩"升级为"最多 4 桩数组":g_t_evc_ii_single_config[MAX_EVC_II_NUM]、g_t_evc_ii_run_info[MAX_EVC_II_NUM],因此几乎所有运行期字段都带 id 索引,二代支持即插即用、刷卡、云平台远程充停、电子锁(枪锁)与 AES 加密通讯。
配置侧由 data/system_config/system_config.c:861 起逐桩初始化并写 Flash(EVC_II_SETTING1_PAGE 等页);运行侧由 midware/interface/interface.c:355 在二代桩使能时调用 evc_ii_control() 驱动。
本头文件同时被 evc_upgrade.c 引用(二代桩升级复用 MAX_EVC_II_NUM、g_t_evc_ii_run_info、g_t_evc_ii_single_config 与加密接口)。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
DEBUG_EVC_II | 宏 | 调试打印开关,值为 0(evc_ii.h:12) |
MAX_EVC_II_NUM | 宏 | 最大并机桩数 4,贯穿全部数组维度(evc_ii.h:14) |
FW_TYPE_EVC_II_TRIPHASE | 宏 | 三相桩型号 "SMILE-G3-EVCT11/S"(evc_ii.h:16) |
FW_TYPE_EVC_II_SINGLE | 宏 | 单相桩型号 "SMILE-G3-EVCS7/S"(evc_ii.h:17) |
FW_TYPE_EVC_II_SINGLE_E | 宏 | 单相增强型型号 "SMILE-G3-EVCS7-E/S"(evc_ii.h:18) |
VERSION_EVC_II_HARD | 宏 | 硬件版本 "V1.02"(evc_ii.h:19) |
EVC_REMOTE_ALLOW / EVC_REMOTE_DENY | 宏 | 远程控制语义显式化:0 = 允许充电,1 = 禁止充电(evc_ii.h:22-23) |
NOMINAL_VOLTAGE_V | 宏 | 额定电压 2300(0.1V 单位 → 230.0V),用于按实测电压修正启动功率(evc_ii.h:25) |
EVC_II_START_MODE_E | 枚举 | 启动模式:NOT_START(0)/EMS_START(1)/CARD_START(2)/PLUG_PLAY_START(3),比一代多即插即用(evc_ii.h:28) |
EVC_II_CHARGE_MODE_E | 枚举 | 充电指令:DEFAULT_CHARGE(0)/STOP_CHARGE(1)/START_CHARGE(2)(evc_ii.h:36) |
EVC_II_CHARGE_PLOT_E | 枚举 | 充电策略:NONE(0)/SLOW(1)/NORMAL(2)/QUICK(3)/SPECIFIED_POWER(4),补上了一代缺失的 0(evc_ii.h:43) |
EVC_II_CHARGE_STATUS_E | 枚举 | 条件充电延迟状态:CHARGE_NORMAL/CONDITION_CHARGE/NO_CONDITION_CHARGE(evc_ii.h:52) |
EVC_II_CHARGE_MODEL_E | 枚举 | 上报云的充电模式:NULL_MODEL(0)/EMS_START_MODEL(1)/CARD_START_MODEL(2)/PLUG_PLAY_MODEL(3)/AVAILABLE_MODEL(4),枚举值连续(evc_ii.h:59) |
EVC_II_CONTROL_MODE_E | 枚举 | 桩侧控制方式:MANUAL_SETTING(0)/TIMING_CHARGE(1)/PLUG_PLAY(2)(evc_ii.h:68) |
EVC_II_SINGLE_CONFIG_T | 结构体 | 单桩设置表:使能、优先级、智能模式、控制方式、相数、三段充电计划(策略 + 使能 + 起止时分 + 最大电流)、枪锁控制、30B 保留、CRC(evc_ii.h:77) |
EVC_II_FAULT_E | 枚举 | 与一代同构的 32 项故障位序号,前缀 EVC_II_FAULT_*(evc_ii.h:118) |
EVC_II_FAULT_U | 联合体 | 32 位故障字三视图:u32_evc_fault_all / byteData[4] / 32 个 bool 位域(evc_ii.h:157) |
EVC_II_RUN_INFO_T | 结构体 | 单桩运行数据总表,数组 g_t_evc_ii_run_info[4] 的元素类型(evc_ii.h:202) |
evc_ii_state_u | 联合体 | 桩状态字:startmode:2/chargingfull:1/chgsts:4/charge_en:1/lock_status:2/ocppflag:2/cardflag:2/gun_lock_flag:2(evc_ii.h:214) |
evc_ii_tags_u | 联合体 | 控制状态:rechargeable/server_control/full_tag(evc_ii.h:232) |
evc_ii_mode_contrl_u | 联合体 | 模式控制字节:chg_mode:4(0 = 联网模式,6 = EMS 模式)、plug_play_ctrl:2、gun_lock_ctrl:2(evc_ii.h:278) |
evc_ii_set_u | 联合体 | 下发控制字:remotcontrol:1(0 允许 / 1 禁止)、phasecontrol:2(evc_ii.h:289) |
evc_ii_flag_u | 联合体 | 软件标记:comm_flag、clear_energy_flag、get_prvite_key_flag(evc_ii.h:299) |
EVC_II_RUN_INFO_T 中的刷卡/定时/云端辅助字段 | 结构体成员 | charge_delay_flag+charge_dealy_tick(条件充电延时)、card_stop/card_start(刷卡启停在途标志)、timer_stop_flag(定时停充状态 0/1/2)、cloud_charge_cmd+cloud_charge_cmd_pending(云指令暂存与待处理)(evc_ii.h:312-318) |
EVC_II_CONTROL_PARA_T | 结构体 | 功率计算中间量:桩数、整体策略 u8_evc_plot、最大充电电流、A/B/C 相与总可充功率(evc_ii.h:322) |
EVC_II_SYS_DATA_T | 结构体 | 系统侧快照:并网状态、电表丢失、三相电压功率、逆变器、电池 SOC/功率/充放限值、各截止 SOC,与一代 EVC_SYS_DATA_T 同构(evc_ii.h:333) |
g_t_evc_ii_single_config[4] | 全局数组 | 4 桩设置表(evc_ii.h:371) |
g_t_evc_ii_run_info[4] | 全局数组 | 4 桩运行数据(evc_ii.h:372) |
3. 函数清单
本文件为纯声明头文件,不含函数定义,仅导出 13 个原型。
| 函数名 | 作用域 | 说明 |
|---|---|---|
evc_ii_control | 全局(声明,evc_ii.h:375) | 二代多桩周期控制主入口,定义于 evc_ii.c:1716 |
get_evc_ii_enable_flag | 全局(声明,evc_ii.h:376) | 任一桩使能即返回 TRUE,定义于 evc_ii.c:1969 |
get_evc_ii_type | 全局(声明,evc_ii.h:377) | 按已识别的型号字符串返回型号,定义于 evc_ii.c:2033 |
get_evc_ii_power_total | 全局(声明,evc_ii.h:378) | 4 桩功率求和,定义于 evc_ii.c:2056 |
get_evc_ii_energy_total | 全局(声明,evc_ii.h:379) | 4 桩电量求和,定义于 evc_ii.c:2074 |
clear_evc_ii_energy | 全局(声明,evc_ii.h:380) | 按 id 清电量(0 = 全部),定义于 evc_ii.c:2120 |
set_evc_ii_charge_flag | 全局(声明,evc_ii.h:381) | 写入指定桩的云端充停指令(带 pending 标志),定义于 evc_ii.c:2151 |
get_evc_ii_chargemodel | 全局(声明,evc_ii.h:382) | 返回指定桩上报云端的充电模式,定义于 evc_ii.c:1995 |
evc_ii_aes_decrypt | 全局(声明,evc_ii.h:383) | AES 解密接口原型;在本工程中只声明未定义(详见第 7 节) |
evc_ii_aes_encrypt | 全局(声明,evc_ii.h:384) | AES 加密 + 4 字节明文头封装,定义于 evc_ii.c:2173 |
get_evc_ii_pravite_key | 全局(声明,evc_ii.h:385) | 通过 0x0300 读取桩内私钥并解密,定义于 evc_ii.c:470 |
get_evc_ii_gun_lock_flag | 全局(声明,evc_ii.h:386) | 把 4 桩枪锁状态压成 1 字节(每桩 2bit),定义于 evc_ii.c:2091 |
get_evc_ii_gun_lock_ctrl | 全局(声明,evc_ii.h:387) | 把 4 桩枪锁使能压成 1 字节(每桩 1bit),定义于 evc_ii.c:2106 |
4. 核心逻辑解析
本文件不含可执行逻辑,其中枢作用在于多桩数组 + 位域布局 + 加密开关三个数据契约。
4.1 多桩数组契约
- 全部运行期循环都以
for (size_t i = 0; i < MAX_EVC_II_NUM; i++)展开,MAX_EVC_II_NUM = 4(evc_ii.h:14)。任何"桩数 > 4"的配置都会被静默截断。 EVC_II_RUN_INFO_T中不含u16_evc_ii_num字段,因此"当前实际启用桩数"没有单一的权威来源;evc_ii_control每次进入都要现算l_u8_evc_cnt(evc_ii.c:1735-1741),evc_ii.c:1811用l_u8_evc_cnt > 1区分"并机分配"与"单桩计算"两条完全不同的功率路径。- 数组下标与 Modbus 从站地址强绑定为
id + 1(evc_ii.c:479、evc_ii.c:546),即id=0→ 地址 1,设备地址不可单独配置。
4.2 位域语义(与协议强耦合)
evc_ii_state_u 共用一个 u16(evc_ii.h:214),但只用了低 16 位中的 15 位,且相邻字段跨字节分布:
bit: 15 14 | 13 12 | 11 10 | 9 8 | 7 6 5 4 | 3 | 2 1 | 0
字段: gun_lock_flag | cardflag | ocppflag | lock_status | chgsts | chargingfull | startmode | charge_en
evc_ii.c:650 以 u16_all 整体接收后,evc_ii.c:652 用 gun_lock_flag != 0 折算成"有枪插入"信号并或入 g_system_function_info.u_system_function1.bit.u8_evc_gun_lock(声明见 data/system_config/system_config.h:202)。
evc_ii_mode_contrl_u(evc_ii.h:278)是 u8,但 evc_ii.c:763-764 却按 u16 取值后拆高/低字节下发(>>8 恒为 0,>>0 才是有效值),属类型与访问方式不匹配的写法,结果正确但冗余。
evc_ii_set_u 的 phasecontrol:2 既承载相数(1 或 3),又被重载为"电流控制开关"——evc_ii.c:733 的设定电流计算公式直接除以它,evc_ii.h:22-23 的远程语义宏只覆盖 remotcontrol。
4.3 加密开关字段
u8_evc_ii_encryption_flag(evc_ii.h:310)与 u8_evc_ii_pravite_key[32](evc_ii.h:311)成对出现:
get_evc_ii_pravite_key()成功后置u8_evc_ii_encryption_flag = TRUE(evc_ii.c:498);- 之后所有报文在
evc_ii_master_send_cmd(evc_ii.c:82)与evc_ii_master_recv_data(evc_ii.c:151)中自动走 AES 分支; - 失败但有响应时置 FALSE(
evc_ii.c:512),即"兼容不支持加密的老桩"。
这一字段使同一份代码能同时对接加密与非加密桩,但也意味着加密协商只在首次上电轮询时进行一次(get_prvite_key_flag 一旦为 TRUE 就不再重试,evc_ii.c:1768-1770)。
4.4 卡片/云端状态字段
card_stop/card_start(evc_ii.h:314-315)是"刷卡指令在途"的辅助标志,语义为"已发起但桩尚未确认",配合 u8_send_control_start_cmd_flag 组成两阶段确认:evc_ii.c:1128-1132 先置 card_start=1,等下一周期确认后再清(evc_ii.c:1154-1158)。
cloud_charge_cmd / cloud_charge_cmd_pending(evc_ii.h:317-318)是本工程较新的"云指令延迟生效"机制:set_evc_ii_charge_flag() 只写命令与置 pending(evc_ii.c:2159-2160),真正的状态机在 evc_ii_update_charge_control_state() 开头消费(evc_ii.c:1106-1110),避免云端写值被同一周期内的本地状态机覆盖。
5. 对外接口
导出的函数(供外部调用)
evc_ii_control():midware/interface/interface.c:355。get_evc_ii_enable_flag():interface.c:331。get_evc_ii_power_total():data/resume_data/flash/flash_data_store.c:673、logic/logic.c:165、net/ems.c:540。get_evc_ii_energy_total():flash_data_store.c:1037、midware/interface/modbus/modbus.c:937/948、net/ems.c:764。get_evc_ii_chargemodel(id):modbus.c:960/1191/1422/1653、net/ems.c:1045。get_evc_ii_type():net/ems.c:3019/3100、net/server.c:3309/3710。clear_evc_ii_energy(id):net/server.c:1226。set_evc_ii_charge_flag(id, flag):net/server.c:1776。get_evc_ii_gun_lock_flag():net/ems.c:1458。get_evc_ii_gun_lock_ctrl():net/ems.c:1979。get_evc_ii_pravite_key(id):evc_upgrade.c:468。evc_ii_aes_encrypt():evc_upgrade.c:67。evc_ii_aes_decrypt():仅声明,无调用方、无定义。
导出的全局变量
g_t_evc_ii_single_config[4]:被data/system_config/system_config.c:861起初始化并写 Flash、被evc_upgrade.c:715读取使能状态、被evc_ii.h使用者配置。g_t_evc_ii_run_info[4]:被data/fault_warn_log/fault_warn_log.c:1147-1187读故障字、被evc_upgrade.c:449写chgsts。
本文件依赖的外部声明
includes.h(evc_ii.h:9)、midware/debug/debug.h(evc_ii.h:10);结构体定义间接依赖 data/system_config/system_config.h 的 ASSERT_FLASH_SECTOR_SIZE。头文件本体不调用任何外部函数。
6. 依赖关系
- 依赖:
includes.h、midware/debug/debug.h;间接依赖data/system_config/system_config.h(ASSERT_FLASH_SECTOR_SIZE)。 - 被依赖:
midware/evc/evc_ii.c(evc_ii.c:13,主实现)midware/evc/evc_upgrade.c/evc_upgrade.h(evc_upgrade.c:17、evc_upgrade.h:11,二代桩升级)midware/interface/interface.c、midware/interface/modbus/modbus.c、data/system_config/system_config.c、data/fault_warn_log/fault_warn_log.c、data/resume_data/flash/flash_data_store.c、logic/logic.c、net/ems.c、net/server.c
7. 备注与风险点
evc_ii_aes_decrypt只声明未定义(evc_ii.h:383):全工程搜索该符号(含.c/.h)只在本行出现,evc_ii.c也没有定义。虽然当前无人调用(解密由common/aes的AESDecrypt在evc_ii.c:154直接完成),但它是悬空的对外接口声明,若被其它模块引用会在链接期报未定义符号。evc_ii_state_u位域越界隐患(evc_ii.h:214-229):声明为u8的位域成员共 2+1+4+1+2+2+2+2 = 16 bit,承载它们的u16_all刚好 16 位,但成员全为u8类型。C 语言中不同u8位域会跨字节分配,实际布局依赖编译器(Keil ARMCC)实现;一旦换编译器或加#pragma pack组合变化,cardflag/gun_lock_flag的位置会漂移,导致刷卡与枪锁逻辑失效。EVC_II_SINGLE_CONFIG_T的u8_reserver[30](evc_ii.h:111):30 字节保留区参与 Flash CRC 与STATIC_ASSERT的分页整除计算(evc_ii.h:115),改动结构体会使已出货设备的配置页 CRC 失配并被判为无效配置。u8_smart_mode与u8_charge_tactics语义重叠(evc_ii.h:82-83):u8_charge_tactics决定三段计划/即插即用/手动三种模式,u8_smart_mode则只在evc_ii.c:1665的"启动功率不足"分支里额外把相数降为 1。两者命名近似但作用点完全不同,易被配置工具混淆。NOMINAL_VOLTAGE_V = 2300是魔法常量(evc_ii.h:25):直接以 0.1V 单位写整数,未定义"单位是 0.1V"的注释(一代同位置evc.c:839直接写裸数2300)。电压实际为 240V 场景下启动功率会偏差约 4%。evc_ii_set_u高位冗余(evc_ii.h:289):u16_all只有 3 位有效,其余 13 位原样下发(evc_ii.c:757-758),若这些位被误置会影响桩侧解释;建议下发前掩码。charge_dealy_tick拼写错误(evc_ii.h:313,"dealy" 应为 "delay"),该拼写已在evc_ii.c:1663/1672/1680/1687多处沿用,改名会波及多处,属历史遗留。EVC_II_START_MODE_E与EVC_II_CHARGE_MODEL_E值域不一致:PLUG_PLAY_START = 3而 enum 内EVC_II_START_MODE_E无AVAILABLE项;上报用的EVC_II_AVAILABLE_MODEL = 4表示"已连接不可充",语义上与startmode正交,云端解析时需按不同字段区分。EVC_II_CONTROL_PARA_T里同时存在"整体策略"u8_evc_plot与"最大充电电流"u16_max_charge_cur(evc_ii.h:325-326),而每桩运行表里也有同名u8_evc_plot/u16_max_charge_cur(evc_ii.h:269-270)。二者在evc_ii.c:434被"以最后一桩可充桩的策略覆盖整体"的方式赋值,多桩策略不一致时整体策略是不确定的。