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

meter_download.h

源文件路径:net/meter_download.h 所属模块:net(网络应用层 / 设备固件升级下载) 代码行数:21

1. 文件职责

本文件是 net/meter_download.c 的对外接口头文件,声明电表(Meter)固件升级流程的 6 个接口:文件掩码查询、升级对象(电网表 / 光伏表 / 正泰无线表)的读写、强制下载标志、下载百分比,以及一个无实现的旧接口 Get_Meter_Ver_From_Server。

它在工程中承担一个特殊职责——暴露"本次升级对象"这一状态。因为工程里多种电表型号共用同一个 UPDT_Meter 升级槽位,get_meter_updt_object() 的返回值被 net/ems.c、net/server.c 与 midware/meter/* 大量用于把对象编号翻译成机型串与硬件版本,从而让云端能够正确匹配固件。

本文件不含逻辑与状态,只含 include guard、一个 include 和 6 个函数原型。

2. 关键数据结构与宏

名称类型说明
__METER_DOWNLOAD_H__宏include guard(第 9-10 行)
Get_Meter_Ver_From_Server函数原型char *Get_Meter_Ver_From_Server(void),工程内无定义、无调用点(见第 7 节备注 1)
get_Meter_Updt_File_Mask函数原型char* get_Meter_Updt_File_Mask(void),定义于 meter_download.c:40
set_meter_updt_object函数原型void set_meter_updt_object(u8 object),定义于 meter_download.c:58
get_meter_updt_object函数原型u8 get_meter_updt_object(void),定义于 meter_download.c:69
IsDownloadMeter函数原型u8 IsDownloadMeter(void),定义于 meter_download.c:80
GetPercentDownloadMeter函数原型u8 GetPercentDownloadMeter(void),定义于 meter_download.c:91

本文件不定义结构体、枚举、联合体、位域,也没有除 include guard 外的宏常量。u8 来自第 12 行 #include <includes.h>。

与本头文件接口配套的枚举 METER_SITE_E(midware/meter/meter.h:163)定义了 u8_upgrade_object 的合法取值范围:GRID_METER = 1、PV_METER、CHNT_WIRELESS、MID_METER、MAX_METER_SITE。本头文件没有引用该枚举,因此接口无法在类型层面约束对象编号。

3. 函数清单

函数名作用域说明
Get_Meter_Ver_From_Server全局(原型声明)语义应为“取服务器下发的电表版本”,全工程无定义、无调用点,属死声明(电表硬版本实际由 midware/meter/meter.h:488 的 meter_read_hard_version(u8 site) 提供)
get_Meter_Updt_File_Mask全局(原型声明)返回 stUpt[UPDT_Meter].as8FileMask,空串时回退 FILE_MASK_DEFAULT("00000000"),定义于 meter_download.c:40
set_meter_updt_object全局(原型声明)写入 stUpt[UPDT_Meter].u8_upgrade_object(无范围校验),定义于 meter_download.c:58
get_meter_updt_object全局(原型声明)读取 stUpt[UPDT_Meter].u8_upgrade_object,定义于 meter_download.c:69
IsDownloadMeter全局(原型声明)查询云端是否下发过电表强制下载标志,定义于 meter_download.c:80
GetPercentDownloadMeter全局(原型声明)查询电表固件下载百分比(0~100),定义于 meter_download.c:91

共 6 个原型声明:5 个有实现、1 个无实现。无 static 函数、无函数指针、无回调、无宏函数。

4. 核心逻辑解析

本文件是纯声明文件,不含可执行逻辑。接口契约要点:

4.1 升级对象接口是"带外"状态,类型不受约束

set_meter_updt_object(u8 object) 的参数是裸 u8,而不是 METER_SITE_E(midware/meter/meter.h:163)。合法值是 GRID_METER(1) ~ MID_METER(4),小于 MAX_METER_SITE(5)。写侧唯一调用点是:

set_meter_updt_object(atoi((char *)g_au8FWBuf));   // net/server.c:2434,来自云端 JSON 的 PARA3
set_meter_updt_object(GRID_METER);                 // net/server.c:2440,BB 升级固定为电网表

由于 atoi 对非法输入返回 0、对超长数字可能回绕,本接口无法保证写入值是合法站点编号。后续该值被直接当作 meter_read_hard_version(site)(midware/meter/meter.h:488)与 meter_get_meter_modle(site)(midware/meter/meter.h:485)的 site 参数使用,共 15 处调用点(见 meter_download.c.md 第 4.1 节表格)。建议签名改为 void set_meter_updt_object(METER_SITE_E object) 并在实现中校验。

4.2 文件掩码的空串兜底语义

get_Meter_Updt_File_Mask() 在 as8FileMask 为空串时返回 FILE_MASK_DEFAULT("00000000")。该返回值参与 8 处掩码匹配(net/ems.c:2977、:3007、:3088;net/server.c:3299、:3469、:3708、:3764、:3803),而没有任何分支匹配 "00000000",因此兜底的实际效果是"不匹配任何升级类型",即丢包重来。调用方无法区分"云端未下发掩码"与"掩码确实全 0"。

4.3 进度与标志的契约

4.4 通信协议 / 定时 / uCOS-II

均不涉及。本文件不定义帧格式、起始码、长度、命令字、校验方式或超时重试参数,不声明信号量、消息邮箱或任务,也不引用 uCOS-II API。所声明的函数由调用方在自己的任务上下文同步调用。

5. 对外接口

导出(供外部使用):

名称使用方
get_Meter_Updt_File_Masknet/ems.c:2977、:3007、:3088;net/server.c:3299、:3469、:3708、:3764、:3803
set_meter_updt_objectnet/server.c:2434、:2440(唯一调用者)
get_meter_updt_objectnet/ems.c:2979、:3009、:3090;net/server.c:3299、:3708;midware/meter/meter.c:5731/5745/5759/6838/6851/6864;midware/meter/meter_upgrade.c:294/298/302/436/442
IsDownloadMeterhmi/ui/ui_main.c:862、net/ems_download.c:259
GetPercentDownloadMeterhmi/ui/ui_main.c:868
Get_Meter_Ver_From_Server无(无定义、无调用)

被调用(本文件引用的外部符号):

名称来源
includes.h第 12 行 #include <includes.h>,提供 u8 等基础类型,并间接引入 uCOS-II 与 GD32 头文件

本文件不导出全局变量,也不引用外部全局变量。

6. 依赖关系

依赖:

被依赖(include 本头文件的文件,共 9 处):

7. 备注与风险点

  1. Get_Meter_Ver_From_Server 声明无实现:全工程(.c / .h)中该标识符只出现于本文件第 15 行,既无定义也无调用。电表硬版本当前由 midware/meter/meter.h:488 的 meter_read_hard_version(u8 site) 提供(net/ems.c:2979 使用),midware/meter/meter.h:485 的 meter_get_meter_modle(u8 site) 提供机型串。这两个函数都要求传入站点编号,而本文件把站点编号状态的读写接口暴露出来正是为此。该声明应删除。
  2. 文件头 @file 与真实文件名不符 + @author 不一致:第 2 行写 meter_download.h(此处一致),但第 3 行 @author 是 Alpha g_stEMSInfo Team,与 meter_download.c 的 Alpha EMS Team 不一致(推测是历史上把标识符 EMS 批量替换为 g_stEMSInfo 时误改了注释);@date 为 2017/05/18,与 bms/evc/inv 三个 download 文件同源。
  3. get_Meter_Updt_File_Mask 返回 char* 而非 const char*:函数既可能返回内部数组 stUpt[UPDT_Meter].as8FileMask 的地址,也可能返回字符串字面量 FILE_MASK_DEFAULT 的地址(只读段)。调用方若尝试写入返回值,前者会破坏升级状态、后者会写入只读内存触发 HardFault。加 const 修饰可让编译器拦截这类误用。
  4. set_meter_updt_object 缺少参数类型约束与范围校验:签名用裸 u8(见 4.1),实现(meter_download.c:58-61)也不校验范围。唯一写侧来自 atoi 的不可信输入(net/server.c:2434),非法值会被无告警地存入,随后 15 处调用点以它为索引/参数使用 meter_read_hard_version() / meter_get_meter_modle()。
  5. net/ems_download.c 以错误大小写包含本头文件:net/ems_download.c:20 写的是 #include "Meter_download.h"(首字母大写),真实文件名是全小写。Windows / Keil MDK 文件系统不区分大小写,能正常编译;迁移到区分大小写的工具链(Linux GCC、大小写敏感检出)会报"找不到文件"。对比同文件 :30 的 afci_download.h 用小写,可判定是笔误。
  6. 接口未暴露"下载完成"状态:与 bms_download.h(IsUpgradeBMS)、afci_download.h(is_afci_firm_download_finished)、inv_download.h(is_inverter_firm_download_finished)相比,本文件没有对应接口,电表的下载完成状态只能通过通用接口 Get_Status_Is_Updated_From_Server(UPDT_Meter) 读取,与同族文件风格不统一。HMI 的"upgrade Meter"分支用的是 midware/meter 的 IsUpgradeMeter() / GetPercentUpgradeMeter()(hmi/ui/ui_main.c:871、:877),属于刷写阶段而非下载阶段。
  7. 升级对象状态的隐式生命周期:u8_upgrade_object 只由 net/server.c:2434/2440 写入,且从不清零;上电初值为 0(不在 METER_SITE_E 合法范围内)。若在收到过升级对象之前就有代码调用 get_meter_updt_object(),会拿到 0 并传给 meter_read_hard_version(0) / meter_get_meter_modle(0)。net/ems.c:2979 等读点全部在"掩码已匹配 get_Meter_Updt_File_Mask()"的条件下才执行,实际很难命中 0,但这依赖调用顺序而非显式保护。