EMS 知识库
首页 / 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宏 0x08002048 的十六进制写法。本工程内无任何引用,属遗留宏
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. 核心逻辑解析

头文件本身不含逻辑,但结构体字段的排列与默认值语义决定了下游状态机行为,理解时需要留意三点:

  1. SENERGYS5_UPGRADE_STATUS_E 的第一个枚举值是 0,而升级上下文被 memset(..., 0, ...) 复位后 upgrade_status 也为 0。因此"复位"等同于"重新回到 SENERGYS5_ENTER_BOOT"。这个设计被 set_upgrade_s5.c 的 SENERGYS5_UPGRADE_END 分支大量依赖(见该文件 4.6 节)。
  2. u8_upgrade_buf[2048] 一缓冲两用:前 1~9 字节在 ENTER_BOOT/SHAKE_HANDS 阶段被当作命令字节数组(buf[8] 是期望应答码),进入 SEND_UPGRADE_FILE 后被 senergys5_fill_dsp_upgrade_data() 整体覆盖为数据块。这种复用省了 2 KB RAM,但要求严格的状态顺序,任何乱序调用都会破坏命令字段。
  3. #pragma pack(1) 且固定地址放置:结构体体积约 2 KB + 头部字段,被放在 SDRAM 中预留的 3 KB 区域(hardware/sdram/sdram.h:67 已标注 Len:3k)。紧凑打包 + 固定地址意味着该结构体的任何字段增删都会改变 SDRAM 布局,属于隐含的持久化格式约束。

5. 对外接口

导出(供其他模块使用):

名称使用者(真实搜索结果)
s_senergys5_upgrade_infoset_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. 依赖关系

7. 备注与风险点

  1. SENERGYS5_INV_UPDATE_SIZE(第 19 行,0x0800)与 SENERGYS5_INV_BLOCK_SIZE(第 20 行,2048)语义完全重复,且前者全工程零引用。两个"同一个 2048"的宏并存,后续若有人改了其中一个会造成隐性不一致。
  2. SENERGYS5_UPGRADE_NONE = 0 全工程零引用:它虽然语义清晰("无升级对象"),但实际代码从不判等它,而是靠 u8_upgrade_object 的取值分支 + 三个 flag 的布尔组合来推断。这个枚举值事实上是死代码。
  3. SENERGYS5_UPGRADE_OBJECT_E 与 SENERGYS5_UPGRADE_STATUS_E 都以 0 起始且含义不同,而 SENERGYS5_ENTER_BOOT = 0 又与 memset 零值重合。任何"忘记显式赋状态"的路径都会静默落入 ENTER_BOOT,属于易错设计。
  4. u8_upgradr_err_count、u32_upgradr_file_size、u32_upgradr_block_count 三处拼写错误(upgradr 应为 upgrader / upgrade),已在 set_comm_usart_s5.c、midware/bms 等多处被跟随使用,改名成本已很高,只能作为已知历史包袱记录。
  5. u8_upgrade_addr 是非 const 裸指针,却指向 SDRAM 中的固件只读区(g_u8_fw_sdram1/2)。类型上没有 const 保护,任何误写都会直接破坏待升级固件且难以察觉。
  6. 固定 SDRAM 地址放置的结构体没有 magic / version 字段。若固件版本升级导致 SENERGYS5_UPGRADE_INFO_T 布局变化,而 SDRAM 内容在软复位后仍保留,则会被新版本固件按新布局误解释(例如 upgrade_status 落在错误偏移上,可能直接进入某个升级状态)。建议增加版本校验字段或改用带 CRC 的持久化结构。
  7. 头文件声明的是 10 个函数,但实现文件里还有 6 个 static 辅助函数未在头文件体现,协议帧的字节级格式(如 0x01/0xA0/0x05 命令头、0x08 0x00 长度前缀)完全没有在头文件里以宏形式暴露,导致"协议字典"职责缺失,只能读 .c 才能知道帧格式。
  8. SENERGYS5_INV_REPLY_CODE1(0x55)与 ENTER_BOOT 阶段主机使用的期望应答码 0x55 数值相同但语义不同:前者是"通信探测的备选应答",后者是"主机进 Boot 的确认码"。同一个常量在不同上下文含义不同,但头文件里只有一个宏,容易被误认为同一件事。