EMS 知识库
首页 / knowledge/代码解析/midware/inverter/inovance

inovance_upgrade.h

源文件路径:midware/inverter/inovance/inovance_upgrade.h 所属模块:midware/inverter/inovance(汇川逆变器通信与固件升级) 代码行数:93

1. 文件职责

本头文件是汇川(Inovance)逆变器 MCU1/MCU2/FPGA 固件升级模块的对外契约:定义升级用到的全部协议命令字、寄存器地址、包长、超时等宏常量,定义返回码/升级对象/状态机三组枚举,定义升级上下文结构体 INOVANCE_UPGRDADE_T,并声明 7 个对外函数。

它本身不含任何可执行逻辑,是 inovance_upgrade.c(实现)与调用方(inovance_comm_usart.c、inverter.c)之间的接口层。数据流位置处于「云端固件已落到 SDRAM → 通过 USART2 写入逆变器 bootloader」这一段,头文件负责把这段流程的帧字段常量与状态枚举固定下来。

INOVANCE_UPGRDADE_T 结构体的实例并不在本头文件声明(inovance_upgrade.c:24 内以 static 单例 s_t_inovance_upgrade 存在),因此本头文件只导出类型定义,不导出任何变量。

2. 关键数据结构与宏

名称类型说明
INOVANCE_UPGRDADE_T结构体升级上下文。u8* u8_upgrade_addr:SDRAM 中的固件镜像基址;u8 u8_upgrade_obj:升级对象(取值见 INOVANCE_UPGRADE_OBJ_E);u8 u8_upgrade_state:定义但全工程未使用(状态实际存在 inovance_upgrade.c 的 static 变量里);u8 u8_upgrade_buf[264]:单包固件数据缓冲;u32 u32_file_offset:已下发偏移;u32 u32_file_length:镜像总长
INOVANCE_UPGRADE_RETURN_E枚举返回码/设备状态混合枚举,三组语义不同的取值重叠在同一枚举内(详见第 7 节风险点)
INOVANCE_UPGRADE_OBJ_E枚举升级对象:INOVANCE_NONE=0、INOVANCE_MCU1=1、INOVANCE_MCU2=2、INOVANCE_FPGA=3、INOVANCE_INIT=4、INOVANCE_MAX=5
INOVANCE_UPGRADE_STATE_E枚举升级状态机状态:INOVANCE_UPGRADE_INIT=0、QUERY_STATUS、JUMP_BOOT、SET_DOWNLOAD_MODE、SEND_FILE、START_PROGRAM、END
INOVANCE_UPGRADE_DEBUG宏(0),本模块调试打印总开关。置 1 后 inovance_upgrade.c 各状态进入/退出均 printf 详细过程
INOVANCE_UPGRADE_ADDR_READ_DEV_STATUS宏(0x04),APP_OPERATE(0x45) 命令读设备状态的寄存器地址
INOVANCE_UPGRADE_ADDR_JUMP_BOOT宏(0x05),APP_OPERATE(0x45) 命令跳转 bootloader 的寄存器地址
INOVANCE_UPGRADE_CMD_APP_OPERATE宏(0x45),APP 操作命令字(查状态 / 跳 boot 共用)
INOVANCE_UPGRADE_CMD_SET_DOWNLOAD_MODE宏(0x64),令 boot 进入下载模式
INOVANCE_UPGRADE_CMD_SEND_FILE宏(0x69),下发固件数据包
INOVANCE_UPGRADE_CMD_START_PROGRAM宏(0x70),启动新程序(校验 + 跳转)
INOVANCE_UPGRADE_FILE_LENGTH宏(264),单包固件数据长度;同时是 u8_upgrade_buf 的容量、以及「总长必须被其整除」的校验模数
INOVANCE_UPGRADE_DELAY宏(200),QUERY_STATUS 状态收不到应答时的时间片延时(ms)
INOVANCE_SLAVE_ADDRESS宏(外部引入)(0x01),来自 inovance_comm_usart.h:40,全部下发帧的从机地址
INOVANCE_DAT_PCK_INTERVAL_INV宏(外部引入)(100),来自 inovance_comm_usart.h:25,用作命令帧的发送节流窗口与串口发送超时(ms)

3. 函数清单

本文件是纯声明头,不含函数定义。下表为头文件中的全部 7 条函数声明:

函数名作用域说明
inovance_read_upgrade_flag_master全局(声明,定义于 inovance_upgrade.c:38)返回主机 MCU1 是否正处于升级中
inovance_read_upgrade_percent_master全局(声明,定义于 inovance_upgrade.c:49)返回主机 MCU1 升级进度百分比
inovance_read_upgrade_flag_slave全局(声明,定义于 inovance_upgrade.c:63)返回从机 MCU2 是否正处于升级中
inovance_read_upgrade_percent_slave全局(声明,定义于 inovance_upgrade.c:74)返回从机 MCU2 升级进度百分比
inovance_read_upgrade_flag_fpga全局(声明,定义于 inovance_upgrade.c:88)返回 FPGA(ARM) 是否正处于升级中
inovance_read_upgrade_percent_fpga全局(声明,定义于 inovance_upgrade.c:101)返回 FPGA(ARM) 升级进度百分比
inovance_upgrade_handle全局(声明,定义于 inovance_upgrade.c:362)升级主状态机入口,每次调用推进一个状态

4. 核心逻辑解析

本文件无运行逻辑,本节说明头文件所「描述」的协议约定与状态模型,细节实现见 inovance_upgrade.c 的对应分析。

4.1 头文件规定的协议帧布局

宏常量决定了 inovance_upgrade.c 中所有下发帧的内容。协议基于 USART2(115200bps)的 Modbus-RTU 风格帧,但用命令字(功能码位)承载自定义语义,帧尾为 Modbus CRC16、低字节先发:

帧用途由哪些宏决定实际字节序列长度
查设备状态INOVANCE_SLAVE_ADDRESS + CMD_APP_OPERATE + ADDR_READ_DEV_STATUS01 45 00 04 00 01 CRC_L CRC_H8
跳转 bootINOVANCE_SLAVE_ADDRESS + CMD_APP_OPERATE + ADDR_JUMP_BOOT01 45 00 05 00 01 CRC_L CRC_H8
进下载模式INOVANCE_SLAVE_ADDRESS + CMD_SET_DOWNLOAD_MODE01 64 F6 0F 00 08 CRC_L CRC_H8
下发固件包INOVANCE_SLAVE_ADDRESS + CMD_SEND_FILE + FILE_LENGTH01 69 <264B> CRC_L CRC_H268
启动新程序INOVANCE_SLAVE_ADDRESS + CMD_START_PROGRAM01 70 00 00 00 00 CRC_L CRC_H8

注意 SET_DOWNLOAD_MODE 帧中的 F6 0F 00 08 在头文件里没有对应宏,是硬编码在 inovance_upgrade.c:287-290 的字面量。

4.2 头文件规定的状态机模型

INOVANCE_UPGRADE_STATE_E 定义了 7 个状态,其序号即状态机的执行顺序,构成一条单向主链:

INIT(0) → QUERY_STATUS(1) → JUMP_BOOT(2) → SET_DOWNLOAD_MODE(3)
        → SEND_FILE(4) → START_PROGRAM(5) → END(6) → 回到 INIT

其中 JUMP_BOOT 只在「APP 仍在运行且处于安全状态」时才经过;若 QUERY_STATUS 发现 APP 已被擦除(异常回复且帧长 8),则直接跳到 SET_DOWNLOAD_MODE。SEND_FILE 单包连续失败 3 次时回退到 QUERY_STATUS 重走一遍;END 之后固定回 INIT,由 INOVANCE_UPGRADE_OBJ_E 的待办标志决定下一个升级对象(MCU1 → MCU2 → FPGA → 结束)。

4.3 头文件规定的时间参数

4.4 与 uCOS-II 的配合

头文件不引入任何 RTOS 原语。它声明的 7 个函数全部由调用方任务同步调用:inovance_upgrade_handle() 由汇川逆变器通信任务(inovance_comm_usart.c:2592)驱动,6 个查询函数由 inverter.c 的只读适配层(:3828/:3863/:3898/:3933/:3984/:4011)调用,均无信号量或消息邮箱参与。

4.5 与结构体相关的全局状态

INOVANCE_UPGRDADE_T 是升级过程的唯一状态载体,但实例由 .c 文件私藏(static INOVANCE_UPGRDADE_T s_t_inovance_upgrade,inovance_upgrade.c:24),头文件只提供类型。因此 6 个 read_* 查询函数是外部读取这些状态的唯一合法途径,u8_upgrade_state 字段则完全闲置。

5. 对外接口

本文件导出

函数声明(7 条):inovance_read_upgrade_flag_master、inovance_read_upgrade_percent_master、inovance_read_upgrade_flag_slave、inovance_read_upgrade_percent_slave、inovance_read_upgrade_flag_fpga、inovance_read_upgrade_percent_fpga、inovance_upgrade_handle。

类型导出:INOVANCE_UPGRDADE_T、INOVANCE_UPGRADE_RETURN_E、INOVANCE_UPGRADE_OBJ_E、INOVANCE_UPGRADE_STATE_E。

宏导出:INOVANCE_UPGRADE_DEBUG、INOVANCE_UPGRADE_ADDR_READ_DEV_STATUS、INOVANCE_UPGRADE_ADDR_JUMP_BOOT、INOVANCE_UPGRADE_CMD_APP_OPERATE、INOVANCE_UPGRADE_CMD_SET_DOWNLOAD_MODE、INOVANCE_UPGRADE_CMD_SEND_FILE、INOVANCE_UPGRADE_CMD_START_PROGRAM、INOVANCE_UPGRADE_FILE_LENGTH、INOVANCE_UPGRADE_DELAY。

不导出任何变量(无 extern 声明)。

实际的调用方:

本文件依赖的外部符号

符号来源
includes.h工程总头文件(:13 include),提供 u8/u16/u32、TRUE/FALSE、RTOS 与 HAL 声明
INOVANCE_SLAVE_ADDRESSmidware/inverter/inovance/inovance_comm_usart.h:40
INOVANCE_DAT_PCK_INTERVAL_INVmidware/inverter/inovance/inovance_comm_usart.h:25

6. 依赖关系

依赖:仅 includes.h(:13)。头文件自身不 include inovance_comm_usart.h,而是寄希望于包含者已经先引入它——INOVANCE_SLAVE_ADDRESS 与 INOVANCE_DAT_PCK_INTERVAL_INV 两个宏在 inovance_upgrade.c 中使用,但本头文件并未声明其来源(见第 7 节风险点)。

被依赖:

7. 备注与风险点

  1. 枚举三域混用,取值重叠:INOVANCE_UPGRADE_RETURN_E(:26-52)把三种互不相干的码表塞进同一个枚举:
    • 设备运行状态:RUNNING=0x01、REVERSE=2、SAFE=3(高字节语义)
    • APP 侧响应错误:CMD_ERROR=0x01、ADDR_ERROR=2、LENGTH_ERROR=3、CRC_CHECK_ERROR=4、JUMPER_DISCONNECT=5
    • boot 侧响应错误:NO_ERROR=0x00、DATA_CRC16_ERROR=1、DECRYPT_ERROR=2、ERASE_ERROR=3、PROGRAM_ERROR=4、CHECK_ERROR=5、DATA_CRC32_ERROR=0x07、ID_ERROR=0x08、CRC32_INCOMPATIBLE_ERROR=0x11、DATA_FRAME_SEND_OVER_LENGTH=0x13、DATA_LENGTH_OUTOF_RANGE=0x14、ADDR_OUTOF_RANGE=0x15、FRAME_NUMBER_ERROR=0x16

例如 INOVANCE_UPGRADE_RUNNING 与 INOVANCE_UPGRADE_CMD_ERROR 都是 1,INOVANCE_UPGRADE_SAFE 与 INOVANCE_UPGRADE_LENGTH_ERROR 都是 3。使用时必须靠「ret >> 8 还是 ret 本身」来区分语义,极易写错。

  1. 枚举内的显式赋值依赖隐式续号:INOVANCE_UPGRADE_CHECK_ERROR 之后写 INOVANCE_UPGRADE_DATA_CRC32_ERROR = 0x07(:44),是为了让后续的 ID_ERROR 顺延为 0x08——而 0x08 正是协议里「ID 错误」的实际码值。这种「靠隐式续号凑上协议值」的写法,一旦在 DATA_CRC32_ERROR 之前插入新项就会静默改变协议语义。
  2. u8_upgrade_state 字段闲置:结构体(:75-83)里的 u8_upgrade_state 在全工程从未被读写,真正的状态保存在 inovance_upgrade.c:364 的 static u8 s_u8_upgrade_state。属于重构残留,容易让阅读者误以为状态存放在结构体里。
  3. 结构体命名拼写错误:类型名是 INOVANCE_UPGRDADE_T("UPGRDADE",多了一个 D、少了 A 的位置),应为 UPGRADE。命名已扩散到 .c 文件,改名需同步多处。
  4. 宏来源未在本头文件引入:INOVANCE_SLAVE_ADDRESS(inovance_comm_usart.h:40)与 INOVANCE_DAT_PCK_INTERVAL_INV(inovance_comm_usart.h:25)在本头文件里既未 #include 也未注释来源,全靠使用处的 include 顺序。若某文件只 include inovance_upgrade.h 并在表达式中用到这两个宏,会直接编译报错。
  5. 无 include guard 保护冲突:守卫宏 __INOVANCE_UPGRADE_H__(:9-10)以双下划线开头,属 C 标准保留给实现的标识符,虽不影响功能但属不规范用法。
  6. F6 0F 00 08 未宏化:CMD_SET_DOWNLOAD_MODE 帧的握手数据域硬编码在 .c 文件里,头文件未给出对应宏(对照 ADDR_READ_DEV_STATUS/ADDR_JUMP_BOOT 都建了宏),协议改动时容易漏改。
  7. 版本/日期字段为空:文件头 @version、@date、@brief 均为空(:4-6),无修订记录可追溯。