evc_download.c
源文件路径:
net/evc_download.c所属模块:net(网络应用层 / 设备固件升级下载) 代码行数:64
1. 文件职责
本文件是 EVC(充电桩 / EV Charger)云端固件下载流程的标志与版本适配层,只有 3 个函数:get_evc_hard_version() 返回 EVC 硬件版本常量,is_download_evc() 查询云端下发的强制下载标志,get_percent_download_evc() 计算下载百分比。
它不参与固件字节的搬运,位置是「EVC 升级状态的只读出口 + 硬件版本上报源」。数据流:云端下发特殊命令 → net/server.c:2346 handle_special_cmd_for_dev() 中 updType == UPDT_EVC 分支置位(server.c:2455 附近还会 set_evc_upgrad_flag())→ is_download_evc() 被 HMI 主界面轮询显示“EVC 下载中 0~100%” → net/ems.c:2984 用 get_evc_hard_version() 把硬件版本上报云端做机型/版本比对 → net/server.c:3675 逐包写入 g_u8_fw_sdram1 → net/upd_download.c:412 MD5 通过后置“已更新完成”位。
驱动方是云端指令(触发下载)与 HMI(消费百分比)。
2. 关键数据结构与宏
| 名称 | 类型 | 说明 |
|---|---|---|
STUpdateTab | 结构体 | 定义于 net/server.h:216;本文件通过通用访问器读取其中的 bIsUpdateForce(强制更新)、u32LenFile(文件总长)、u32OffsetFile(已下载偏移) |
ENUpdateType | 枚举 | 定义于 net/server.h:186;本文件使用 UPDT_EVC(值 6,位于 UPDT_Meter 与 UPDT_AFCI 之间)作为 stUpt[] 下标 |
ST_EMS_INFO(g_stEMSInfo) | 全局结构体实例 | 定义于 net/ems.h;stUpt[UPDT_MAX] 即升级表(net/ems.h:346),本文件唯一的状态来源 |
FILE_MASK_EVC | 宏 | net/server.h:90,值 "00000800";EVC 的升级文件掩码,本文件未直接引用,由 server.c / ems.c 匹配使用 |
VERSION_EVC_HARD | 宏 | midware/evc/evc.h:17,值 "V1.02";本文件把它作为 EVC 硬件版本返回并上报云端 |
DEBUG_EVC_DOWNLOAD | 宏 | 见 evc_download.h:17,值 (0);本文件未使用,全工程也无其他引用(死宏) |
本文件不定义任何结构体、枚举、联合体、位域或宏常量。
需要特别指出:EVC 的机型串(File_Type)不在本文件提供,而由 midware/evc 的 get_evc_type() / get_evc_ii_type() 提供,并由 get_evc_enable_flag() 在一代/二代桩之间二选一(见 net/ems.c:3013-3021、net/server.c:3303-3310、net/server.c:3709-3710)。
3. 函数清单
| 函数名 | 作用域 | 说明 |
|---|---|---|
get_evc_hard_version | 全局 | evc_download.c:37。返回常量 VERSION_EVC_HARD("V1.02"),供云端上报 EVC 硬件版本 |
is_download_evc | 全局 | evc_download.c:49。返回 get_flag_force_update(UPDT_EVC),即云端下发的 EVC 强制下载标志 |
get_percent_download_evc | 全局 | evc_download.c:61。返回 已下载偏移 * 100 / 文件总长 |
共 3 个函数,全部为全局作用域,无 static 函数、无函数指针、无回调、无循环。文件中的函数头注释存在错位与言不符实(见第 7 节)。
4. 核心逻辑解析
4.1 EVC 的“双侧”状态语义
与 BMS 不同,本文件只暴露“下载中”这一侧(is_download_evc()),没有对应的“下载已完成”接口。EVC 完成后的刷写进度由 midware/evc 的 is_upgrade_evc() / get_percent_upgrade_evc() 提供(见 HMI 的 hmi/ui/ui_main.c:889、:895),形成「云端下载(本文件)→ 本地刷写(midware/evc)」两段式显示。
EVC 在强制标志的处理上与 BMS/INV3 同组:net/server.c:2410-2412 在非强制升级时把 UPDT_EVC(连同 UPDT_BMS、UPDT_INV3)的 bIsUpdateForce 显式清零,因此 is_download_evc() 只在“云端强制下载”场景才为真。
4.2 下载百分比公式与取值来源
u8 get_percent_download_evc(void)
{
return get_curr_offset_file_request(UPDT_EVC) * 100 / get_length_file_updating(UPDT_EVC);
} // evc_download.c:61-64
- 分母
u32LenFile:由net/server.c:3318set_file_updating_info_for_dev()从云端 JSON 的Length解析,且必须落在(1024*10, SDRAM_3M)(10 KB ~ 3 MB)区间内才被接受,见net/server.c:3473-3476。 - 分子
u32OffsetFile:由net/server.c:3568increase_current_offset_file_updt()按包长递增(调用点net/server.c:3831)。 - 流程结束(含 MD5 失败)时
net/upd_download.c:429无条件清零u32OffsetFile,百分比自动回落。
4.3 状态迁移(外部状态机,本文件只提供读点)
[云端特殊命令] server.c:2346 handle_special_cmd_for_dev(..., UPDT_EVC, ...)
├─ server.c:2370/2382 set_response_force_upd_status(UPDT_EVC, TRUE)
├─ server.c:2407-2416 强制: set_flag_force_update(UPDT_EVC, TRUE)
│ 非强制: set_flag_force_update(UPDT_EVC, FALSE)
├─ server.c:2418 set_updt_file_mask(UPDT_EVC, FILE_MASK_EVC)
├─ server.c:2422 set_ver_from_server(UPDT_EVC, ver, len)
└─ server.c:2455-2458 set_evc_upgrad_flag(atoi(para3))
↓ is_download_evc()==1 → HMI 进入 “EVC 下载中” 界面
↓ server.c:3473 set_file_updating_info_for_dev(UPDT_EVC, 10K, SDRAM_3M)
↓ server.c:3770 save_fw_to_spi_flash(..., UPDT_EVC) → save_fw_to_sdram(..., g_u8_fw_sdram1)
↓ server.c:3809 calculate_dev_FW_Flash_MD5(UPDT_EVC, g_u8_fw_sdram1, EVC_FIRM_DOWNLOAD)
├─ MD5 一致 → upd_download.c:412 Set_Status_Is_Updated_From_Server(UPDT_EVC, TRUE)
└─ MD5 不一致 → upd_download.c:422 u16_upgrade_error.BIT.md5_error = 1
↓ 之后由 midware/evc 的 is_upgrade_evc() / get_percent_upgrade_evc() 接管刷写显示
4.4 通信协议帧格式与重试机制
本文件不构造/解析报文。相关外部契约:
- 上行的机型/版本字段:
net/ems.c:2984输出Hard_Version = get_evc_hard_version();net/ems.c:3013-3021输出File_Type = get_evc_type()或get_evc_ii_type()(按get_evc_enable_flag()二选一);请求报文由net/ems.c:3042fill_common_data(..., REQUEST_COMM, CMD_CHECK_UPDATE)统一加 7 字节头 + 2 字节校验。 - 下行的包级校验链在
net/server.c:3692起:FileMask(8 字符) →FileOffset(必须等于本地已下载偏移)→FileType(必须命中get_evc_type()或get_evc_ii_type(),server.c:3709-3710)→FileLength(≤LEN_REQ_FILE)→FileData(hex)。任一步失败立即return丢包,等云端超时重发。 - 整卷校验是 MD5(
net/upd_download.c:391),失败只置md5_error位而不置完成位。
4.5 与 uCOS-II 的配合
本文件不含任何 uCOS-II 调用:无任务创建、无信号量、无消息邮箱、无延时。3 个函数都是对 g_stEMSInfo 的同步单次读取。
g_stEMSInfo.stUpt[UPDT_EVC] 由 EMS 网络任务写、由 HMI 任务读,无临界区保护,依赖单字节布尔写入与 u32 对齐访问的原子性。
5. 对外接口
本文件导出(供谁调用):
| 导出名 | 调用方 |
|---|---|
get_evc_hard_version | net/ems.c:2984(组织 checkUpdate 请求的 Hard_Version 字段) |
is_download_evc | hmi/ui/ui_main.c:880;net/ems_download.c:260(IsSystemDownload()) |
get_percent_download_evc | hmi/ui/ui_main.c:886 |
本文件不导出全局变量。
本文件调用的外部符号:
| 名称 | 来源 |
|---|---|
g_stEMSInfo | net/ems.h |
get_flag_force_update / get_curr_offset_file_request / get_length_file_updating | net/upd_download.c(声明于 upd_download.h:26/28/37) |
VERSION_EVC_HARD | midware/evc/evc.h:17 |
6. 依赖关系
依赖(第 13-20 行 include):
upd_download.h、evc_download.h、evc.h、ems.h、server.h、MD5.h、sdram.h、iwdg.h- 其中
MD5.h、sdram.h、iwdg.h在本文件内无任何直接引用(MD5 计算在upd_download.c的calculate_dev_FW_Flash_MD5),是从bms_download.c复制模板时留下的冗余 include。 evc.h是真正的必要依赖,VERSION_EVC_HARD来自它。
被依赖(include evc_download.h 的文件):
net/evc_download.c:14net/ems.c:46、net/server.c:50、net/ems_download.c:21hmi/ui/ui_main.c:29midware/evc/evc.c:14、midware/evc/evc_ii.c:15、midware/evc/evc_upgrade.c:15、midware/interface/interface.c:23
注意:后 4 个 midware 文件 include 了本头文件,但没有使用其中任何一个符号(get_evc_hard_version / is_download_evc / get_percent_download_evc / calculate_evc_flash_md5 在这些文件里均无引用),属于纯冗余 include。
7. 备注与风险点
- 函数头注释与实现完全不符:
evc_download.c:30-36的注释写的是char *get_bms_hard_version(void),实际函数是get_evc_hard_version;:42-48的注释写void is_download_evc(void),实际返回u8;:54-60的注释写void get_percent_download_evc(void),实际返回u8。三处都是从bms_download.c复制后未更新注释。 - 百分比函数存在除零可能:
evc_download.c:63的除数是u32LenFile。bIsUpdateForce在net/server.c:2408置位时文件长度尚未解析(值为 0),HMI 的调用顺序是「先判is_download_evc()再算百分比」(ui_main.c:880、:886),存在分母为 0 的窗口。ARM 平台上 32 位无符号除法除零不触发硬件异常(UDIV或库函数__aeabi_uidiv均返回 0),表现为显示 0% 而非异常。 u8截断:返回u8而中间计算是u32。正常流程比值 ≤ 100;若u32OffsetFile异常超过u32LenFile,结果会被截断。DEBUG_EVC_DOWNLOAD是死宏:定义在evc_download.h:17,但全工程(.c与.h)都没有第二次引用,各函数中的调试打印也因此不存在(本文件没有任何printf)。对比同族文件(如inv_download.c使用DEBUG_TCP_CLIENT_STATE),可知这是未接线的调试开关。@file与真实文件名不符:第 2 行写evc_download.c但第 3 行@author是Alpha g_stEMSInfo Team(与evc_download.h一致,与bms_download.c的Alpha EMS Team不一致),是批量替换注释的遗留。- 缺少“已完成”查询接口:本文件不提供 EVC 的
bIsUpdatedFromServer读取接口,EVC 下载完成状态只能通过通用接口Get_Status_Is_Updated_From_Server(UPDT_EVC)(net/ems_download.c:282使用)获取,与同族的 BMS/AFCI 文件风格不统一。 - 冗余 include:
MD5.h/sdram.h/iwdg.h未被使用,可移除(见 6. 依赖)。