EMS 知识库
首页 / knowledge/代码解析/net

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

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 通信协议帧格式与重试机制

本文件不构造/解析报文。相关外部契约:

4.5 与 uCOS-II 的配合

本文件不含任何 uCOS-II 调用:无任务创建、无信号量、无消息邮箱、无延时。3 个函数都是对 g_stEMSInfo 的同步单次读取。

g_stEMSInfo.stUpt[UPDT_EVC] 由 EMS 网络任务写、由 HMI 任务读,无临界区保护,依赖单字节布尔写入与 u32 对齐访问的原子性。

5. 对外接口

本文件导出(供谁调用):

导出名调用方
get_evc_hard_versionnet/ems.c:2984(组织 checkUpdate 请求的 Hard_Version 字段)
is_download_evchmi/ui/ui_main.c:880;net/ems_download.c:260(IsSystemDownload())
get_percent_download_evchmi/ui/ui_main.c:886

本文件不导出全局变量。

本文件调用的外部符号:

名称来源
g_stEMSInfonet/ems.h
get_flag_force_update / get_curr_offset_file_request / get_length_file_updatingnet/upd_download.c(声明于 upd_download.h:26/28/37)
VERSION_EVC_HARDmidware/evc/evc.h:17

6. 依赖关系

依赖(第 13-20 行 include):

被依赖(include evc_download.h 的文件):

注意:后 4 个 midware 文件 include 了本头文件,但没有使用其中任何一个符号(get_evc_hard_version / is_download_evc / get_percent_download_evc / calculate_evc_flash_md5 在这些文件里均无引用),属于纯冗余 include。

7. 备注与风险点

  1. 函数头注释与实现完全不符: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 复制后未更新注释。
  2. 百分比函数存在除零可能: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% 而非异常。
  3. u8 截断:返回 u8 而中间计算是 u32。正常流程比值 ≤ 100;若 u32OffsetFile 异常超过 u32LenFile,结果会被截断。
  4. DEBUG_EVC_DOWNLOAD 是死宏:定义在 evc_download.h:17,但全工程(.c 与 .h)都没有第二次引用,各函数中的调试打印也因此不存在(本文件没有任何 printf)。对比同族文件(如 inv_download.c 使用 DEBUG_TCP_CLIENT_STATE),可知这是未接线的调试开关。
  5. @file 与真实文件名不符:第 2 行写 evc_download.c 但第 3 行 @author 是 Alpha g_stEMSInfo Team(与 evc_download.h 一致,与 bms_download.c 的 Alpha EMS Team 不一致),是批量替换注释的遗留。
  6. 缺少“已完成”查询接口:本文件不提供 EVC 的 bIsUpdatedFromServer 读取接口,EVC 下载完成状态只能通过通用接口 Get_Status_Is_Updated_From_Server(UPDT_EVC)(net/ems_download.c:282 使用)获取,与同族的 BMS/AFCI 文件风格不统一。
  7. 冗余 include:MD5.h / sdram.h / iwdg.h 未被使用,可移除(见 6. 依赖)。