首页 / knowledge/代码解析/midware/inverter/set
set_upgrade_s5.h
源文件路径:
midware/inverter/set/set_upgrade_s5.h所属模块:midware/inverter/set(盛能杰 S5 / S5-II / M10 逆变器通信) 代码行数:82
1. 文件职责
本头文件是盛能杰 Smile5 逆变器Bootloader 级串口固件升级的对外契约。它定义了升级对象(主机 / 从机 / DCDC)与升级流程状态机(进 Boot、握手、下发文件属性、下发文件、结束)两个枚举、升级上下文结构体 SENERGYS5_UPGRADE_INFO_T,以及 10 个供 inverter.c、set_comm_usart_s5.c 查询升级进度/标志的接口声明。它处在"云端下发固件 → SDRAM 固件区 → 逆变器 DSP/ARM"这条链路的末端,只被同目录的 set_upgrade_s5.c 实现,被 inverter.c 的版本查询接口聚合后暴露给 HMI 与云端。头文件本身无任何可执行逻辑。
2. 关键数据结构与宏
2.1 宏常量
| 名称 | 类型 | 说明 |
|---|---|---|
SENERGYS5_UPGRADE_DEBUG | 宏 0 | 升级流程调试打印总开关(含逐字节打印升级数据),量产为 0 |
SENERGYS5_INV_REPLY_CODE | 宏 0xA5 | 逆变器 Bootloader 通用应答码,握手、文件属性、数据块校验、校验和等多个环节共用 |
SENERGYS5_INV_REPLY_CODE1 | 宏 0x55 | 备用应答码,仅在 set_comm_usart_s5.c:428 的通信状态探测中作为第二候选 |
SENERGYS5_INV_UPDATE_SIZE | 宏 0x0800 | 2048 的十六进制写法。本工程内无任何引用,属遗留宏 |
SENERGYS5_INV_BLOCK_SIZE | 宏 2048 | 升级数据块大小,同时是 u8_upgrade_buf 的容量与逐块发送的字节数 |
SENERGYS5_ADDR_INV_UPADTE_VERSIONS_INFO | 宏 0x1A1C | 主机版本信息寄存器起始地址,升级结束后用于回读校验 |
SENERGYS5_NUM_INV_UPADTE_VERSIONS_INFO | 宏 0x0D | 待回读的寄存器个数(13 个,即 26 字节应答) |
2.2 枚举
| 名称 | 类型 | 说明 |
|---|---|---|
SENERGYS5_UPGRADE_OBJECT_E | 枚举 | 当前升级对象:SENERGYS5_UPGRADE_NONE = 0(未选,工程内无引用)、SENERGYS5_UPGRADE_MASTER = 1(主机)、SENERGYS5_UPGRADE_SLAVE(从机)、SENERGYS5_UPGRADE_DCDC(DCDC/ARM 子模块) |
SENERGYS5_UPGRADE_STATUS_E | 枚举 | 升级状态机:SENERGYS5_ENTER_BOOT = 0(进 Boot + 选定对象)、SENERGYS5_SHAKE_HANDS(握手)、SENERGYS5_SEND_FILE_PROPERTIES(下发文件属性)、SENERGYS5_SEND_UPGRADE_FILE(逐块下发数据)、SENERGYS5_UPGRADE_END(收尾与版本回读)。注意 ENTER_BOOT = 0 与结构体 memset(0) 后的默认值重合,是后文状态复位机制的关键前提 |
2.3 结构体
| 名称 | 类型 | 说明 |
|---|---|---|
SENERGYS5_UPGRADE_INFO_T | 结构体(#pragma pack(1) 紧凑排布) | 升级上下文。成员:u8_upgrade_master_flag/u8_upgrade_slave_flag/u8_upgrade_dcdc_flag 三个待升级标志;u8_upgrade_object 当前对象;u8_upgradr_err_count 重试错误计数(注意拼写 upgradr 为工程内既有笔误);upgrade_status 当前状态;u8_upgrade_addr 固件在 SDRAM 中的基址;u32_upgrade_file_offset 已发送偏移;u32_upgradr_file_size 文件总长(取自文件头);u32_upgrade_file_len 文件实际长度(取自下载模块);u32_upgradr_block_count 总块数;u32_send_block_count 已发块数;u32_check_code 当前块累加校验和;u8_upgrade_buf[2048] 数据块缓冲(前 9 字节兼作命令缓冲);u8_set_dcdc_upgrade_on_flag DCDC 升级后的"需强制关机"标记 |
2.4 对外全局变量与函数声明
| 名称 | 类型 | 说明 |
|---|---|---|
s_senergys5_upgrade_info | 全局变量(extern) | SENERGYS5_UPGRADE_INFO_T 类型,定义在 set_upgrade_s5.c:25,用 __attribute__((at(...))) 定位到固定 SDRAM 地址,因此上电不清零、可跨软复位保留 |
senergys5_get_inv_upgrade_flag | 函数声明 | 主机/从机固件下载完成标志,返回 TRUE 时内部会自动置位 master+slave 待升级标志 |
senergys5_get_dcdc_start_upgrade_flag | 函数声明 | DCDC 固件下载完成标志,返回 TRUE 时内部自动置位 dcdc 待升级标志 |
senergys5_get_master_upgrade_flag | 函数声明 | 当前是否正在升级主机 |
senergys5_get_slave_upgrade_flag | 函数声明 | 当前是否正在升级从机 |
senergys5_get_dcdc_upgrade_flag | 函数声明 | 当前是否正在升级 DCDC |
senergys5_read_upgrade_percent_arm | 函数声明 | DCDC 升级进度百分比(0~100) |
senergys5_read_upgrade_percent_slave | 函数声明 | 从机升级进度百分比 |
senergys5_read_upgrade_percent_master | 函数声明 | 主机升级进度百分比 |
senergys5_upgrade_recv_mdsp | 函数声明 | 按期望应答码轮询串口,成功返回 TRUE;供 set_comm_usart_s5.c 复用做通信状态探测 |
senergys5_inv_upgrade_handle | 函数声明 | 升级状态机单步执行函数,需要被周期调用 |
3. 函数清单
本文件为头文件,仅含函数声明,无函数定义。
| 函数名 | 作用域 | 说明 |
|---|---|---|
senergys5_get_inv_upgrade_flag(void) | 全局(声明) | 查询主机/从机固件下载完成并自动置位待升级标志 |
senergys5_get_dcdc_start_upgrade_flag(void) | 全局(声明) | 查询 DCDC 固件下载完成并自动置位待升级标志 |
senergys5_get_master_upgrade_flag(void) | 全局(声明) | 查询是否在升级主机 |
senergys5_get_slave_upgrade_flag(void) | 全局(声明) | 查询是否在升级从机 |
senergys5_get_dcdc_upgrade_flag(void) | 全局(声明) | 查询是否在升级 DCDC |
senergys5_read_upgrade_percent_arm(void) | 全局(声明) | DCDC 升级百分比 |
senergys5_read_upgrade_percent_slave(void) | 全局(声明) | 从机升级百分比 |
senergys5_read_upgrade_percent_master(void) | 全局(声明) | 主机升级百分比 |
senergys5_upgrade_recv_mdsp(const u8 reply_code, const u32 timeout) | 全局(声明) | 等待指定应答码 |
senergys5_inv_upgrade_handle(void) | 全局(声明) | 升级状态机主处理 |
4. 核心逻辑解析
头文件本身不含逻辑,但结构体字段的排列与默认值语义决定了下游状态机行为,理解时需要留意三点:
SENERGYS5_UPGRADE_STATUS_E的第一个枚举值是 0,而升级上下文被memset(..., 0, ...)复位后upgrade_status也为 0。因此"复位"等同于"重新回到SENERGYS5_ENTER_BOOT"。这个设计被set_upgrade_s5.c的SENERGYS5_UPGRADE_END分支大量依赖(见该文件 4.6 节)。u8_upgrade_buf[2048]一缓冲两用:前 1~9 字节在ENTER_BOOT/SHAKE_HANDS阶段被当作命令字节数组(buf[8]是期望应答码),进入SEND_UPGRADE_FILE后被senergys5_fill_dsp_upgrade_data()整体覆盖为数据块。这种复用省了 2 KB RAM,但要求严格的状态顺序,任何乱序调用都会破坏命令字段。#pragma pack(1)且固定地址放置:结构体体积约 2 KB + 头部字段,被放在 SDRAM 中预留的 3 KB 区域(hardware/sdram/sdram.h:67已标注Len:3k)。紧凑打包 + 固定地址意味着该结构体的任何字段增删都会改变 SDRAM 布局,属于隐含的持久化格式约束。
5. 对外接口
导出(供其他模块使用):
| 名称 | 使用者(真实搜索结果) |
|---|---|
s_senergys5_upgrade_info | set_upgrade_s5.c(读写)、set_comm_usart_s5.c:502/510/2831/2833(初始化清零、置位 DCDC 升级开机标记、读该标记强制逆变器下电) |
senergys5_get_inv_upgrade_flag() | midware/inverter/set/set_comm_usart_s5.c:6201 |
senergys5_get_dcdc_start_upgrade_flag() | midware/inverter/set/set_comm_usart_s5.c:6201 |
senergys5_get_master_upgrade_flag() | set_comm_usart_s5.c:6213、midware/inverter/inverter.c:3812(inverter_read_upgrade_flag_master) |
senergys5_get_slave_upgrade_flag() | set_comm_usart_s5.c:6218、midware/inverter/inverter.c:3882 |
senergys5_get_dcdc_upgrade_flag() | set_comm_usart_s5.c:6223、midware/inverter/inverter.c:3976(inverter_read_upgrade_flag_arm) |
senergys5_read_upgrade_percent_master() | midware/inverter/inverter.c:3847 |
senergys5_read_upgrade_percent_slave() | midware/inverter/inverter.c:3917 |
senergys5_read_upgrade_percent_arm() | midware/inverter/inverter.c:4003 |
senergys5_upgrade_recv_mdsp() | midware/inverter/set/set_comm_usart_s5.c:428(senergy_comm_status_check 通信探测) |
senergys5_inv_upgrade_handle() | midware/inverter/set/set_comm_usart_s5.c:6211 |
依赖的外部符号:includes.h(统一基础类型 u8/u32 与 TRUE/FALSE)。
6. 依赖关系
- 依赖:仅
includes.h。文件不引入任何其它模块头文件,因此SENERGYS5_UPGRADE_INFO_T也不依赖 SDRAM、加密或网络类型(u8*指针为裸指针)。 - 被依赖(真实搜索结果):
midware/inverter/set/set_upgrade_s5.c(唯一实现者)midware/inverter/set/set_comm_usart_s5.c(8 处引用:升级触发、进度上报、DCDC 开关机标记)midware/inverter/inverter.c(6 处聚合出口:inverter_read_upgrade_flag_master/slave/arm、inverter_read_upgrade_percent_master/slave/arm,位于 3812/3847/3882/3917/3976/4003 行)- 上游再由
hmi/net通过inverter.h的inverter_read_upgrade_*接口消费,本文件不直接对外暴露
7. 备注与风险点
SENERGYS5_INV_UPDATE_SIZE(第 19 行,0x0800)与SENERGYS5_INV_BLOCK_SIZE(第 20 行,2048)语义完全重复,且前者全工程零引用。两个"同一个 2048"的宏并存,后续若有人改了其中一个会造成隐性不一致。SENERGYS5_UPGRADE_NONE = 0全工程零引用:它虽然语义清晰("无升级对象"),但实际代码从不判等它,而是靠u8_upgrade_object的取值分支 + 三个 flag 的布尔组合来推断。这个枚举值事实上是死代码。SENERGYS5_UPGRADE_OBJECT_E与SENERGYS5_UPGRADE_STATUS_E都以 0 起始且含义不同,而SENERGYS5_ENTER_BOOT = 0又与memset零值重合。任何"忘记显式赋状态"的路径都会静默落入ENTER_BOOT,属于易错设计。u8_upgradr_err_count、u32_upgradr_file_size、u32_upgradr_block_count三处拼写错误(upgradr应为upgrader/upgrade),已在set_comm_usart_s5.c、midware/bms等多处被跟随使用,改名成本已很高,只能作为已知历史包袱记录。u8_upgrade_addr是非 const 裸指针,却指向 SDRAM 中的固件只读区(g_u8_fw_sdram1/2)。类型上没有const保护,任何误写都会直接破坏待升级固件且难以察觉。- 固定 SDRAM 地址放置的结构体没有 magic / version 字段。若固件版本升级导致
SENERGYS5_UPGRADE_INFO_T布局变化,而 SDRAM 内容在软复位后仍保留,则会被新版本固件按新布局误解释(例如upgrade_status落在错误偏移上,可能直接进入某个升级状态)。建议增加版本校验字段或改用带 CRC 的持久化结构。 - 头文件声明的是 10 个函数,但实现文件里还有 6 个 static 辅助函数未在头文件体现,协议帧的字节级格式(如
0x01/0xA0/0x05命令头、0x08 0x00长度前缀)完全没有在头文件里以宏形式暴露,导致"协议字典"职责缺失,只能读.c才能知道帧格式。 SENERGYS5_INV_REPLY_CODE1(0x55)与ENTER_BOOT阶段主机使用的期望应答码0x55数值相同但语义不同:前者是"通信探测的备选应答",后者是"主机进 Boot 的确认码"。同一个常量在不同上下文含义不同,但头文件里只有一个宏,容易被误认为同一件事。