如何通过STM32H5 Bootloader进行固件升

1. 简介

客户在使用STM32H563开发项目时,希望通过STM32H563的I2C Bootloader实现固件升级,并在升级完成后直接运行程序。由于硬件设计限制,在该过程中无法切换BOOT0引脚状态,也无法使用调试接口。基于客户需求以及STM32H563的器件特性,本文介绍如何通过STM32H563的I2CBootloader相关命令,实现固件升级、Product State切换、OBKEY  Provisioning以及MCU复位。

文中涉及的代码基于两块NUCLEO-H563开发板实现,其中一块作为Host端,另一块作为目标端MCU。Host通过I2C与目标MCU的I2CBootloader通信,从而实现客户所需功能。

2. 实现过程

通过Bootloader进行固件升级与运行用户固件时,STM32H563的启动路径并不相同。

在固件升级过程中,目标STM32H563需要从系统Flash启动,即进入system Bootloader;而在运行用户固件时,则需要从用户Flash启动。根据STM32H563参考手册,可通过两种方式切换启动路径:第一种是切换BOOT0引脚电平,第二种是切换Product State,如图1所示。

Image
如何通过STM32H5 Bootloader进行固件升

▲ 图1. Boot Mode

由于客户硬件设计限制,无法切换BOOT0引脚状态,因此只能通过切换Product State来实现启动路径的切换。

具体步骤如下:

1. BOOT0始终保持高电平,系统上电复位后,目标STM32H563进入Bootloader模式。

2. Host通过I2C Bootloader下载固件。

3. Host通过I2C Bootloader将目标STM32H563的Product State更改为Provisioning状态。

4. Host通过I2C Bootloader将OBKEY数据下载到目标STM32H563中,以确保后续能够正常回退和调试。

5. Host通过I2C Bootloader更改目标STM32H563的Product State为CLOSED状态。

6. Host通过I2C Bootloader复位目标STM32H563。

7. 目标STM32H563从用户Flash启动运行。

2.1. 常见问题与注意事项

在实现上述功能的过程中,主要遇到了以下问题:

1. 当Host与目标H5通过I2C通信时,SCL和SDA必须外接上拉电阻,否则通信无法成功。

2. 传给I2C HAL函数的Slave地址参数应为7位器件地址左移1位后的结果。例如,STM32H563 Bootloader的I2C器件7位地址为0x65,那么Host端调用I2C HAL函数时的地址参数应为0x65 << 1。

3. 在进行OBKEY Provisioning时,原始OBKEY文件头与下载到目标板RAM中所需的OBKEY文件头格式并不一致,因此需要按照手册要求进行修改,否则Provisioning会失败。

4. 在进行OBKEY Provisioning时,需要先将OBKEY下载到目标H563的RAM中,且必须使用SRAM3空间。

5. 案例是基于TrustZone未使能的条件,所以使用的OBKEY需要是带密码的版本。

2.2. 固件升级

在固件升级过程中,主要使用两个命令:Flash擦除命令(0x44)和写Memory命令(0x31)。这些命令的使用方法在AN4221中已有详细描述,只需严格按照文档中的时序实现即可,本文附件中的参考工程对应的BOOT_Erase和BOOT_WriteMem函数实现了上述命令,供用户参考。

基本步骤如下:

1. 根据待下载固件的大小,计算所需的Flash空间,然后发送0x44命令,擦除对应的Flash Pages。

2. 0x31命令每次最多支持写入256字节,Host端可根据固件大小,分多次将数据写入目标Flash区域。

2.3. 更改Product State

STM32H5 Bootloader除了支持常用的命令,还支持Special命令(0x50),这个命令就可以支持Product State修改,Provisioning以及MCU复位操作,这个命令的具体使用说明,要参考AN2606和AN4221,如下图所示。

Image
如何通过STM32H5 Bootloader进行固件升

▲ 图2. Special Commands

参考工程中的BOOT_SP_ProductStateCmd函数实现了该命令,可供用户参考。不同参数对应不同的Product State,参数值如下表所示。

Image
如何通过STM32H5 Bootloader进行固件升

▲ 图3. Product State

2.4. Provisioning OBKEY

OBKEY Provisioning同样使用上述Special Command来完成,整个过程包含两个步骤:

1. 先发送Write Memory(0x31)命令,将OBKEY数据写入目标H563的RAM中。

2. 再发送Special(0x50)命令+Provisioning(0x83)子命令完成Provisioning。Bootloader接收到该命令后,会将RAM中的OBKEY数据写入OBKEY Flash区域。

在实现该命令时,需要特别注意以下几点:

工具生成的OBKEY文件包含Header和Payload。Bootloader执行Provisioning时所使用的OBKEY数据Header与原始OBKEY文件Header不同,因此在将OBKEY下载到目标H563 RAM之前,需要重新计算Header。

存放OBKEY数据的目标RAM必须位于SRAM3地址区域。

上述注意事项在STM32H563的参考手册中已有描述,具体章节如下图所示

Image
如何通过STM32H5 Bootloader进行固件升

▲ 图4. Data Provisioning

参考工程中的Run_ProvisionCmd函数实现了该命令,包含了重新计算OBKEY header头,下载OBKEY到目标H563 RAM中以及发送Provisioning命令,可供用户参考。

2.5. 复位MCU

STM32H563 Bootloader Special命令同样支持复位MCU,这样Host可以发送该命令来复位目标H563。

参考工程中的BOOT_SP_ResetCmd函数实现了该命令,可供用户参考。

3. 参考工程说明

参考工程基于NUCLEO-H563开发板开发,使用MDK-KEIL编译器。工程实现了STM32H563 I2C Bootloader Host侧的大部分命令,以及基于这些命令的固件升级、Product  State修改和OBK Provisioning等测试功能。相关代码主要集中在bootloader.c源文件中。

为便于测试,参考工程还增加了两个汇编文件:OBKey.s和targetApp.s。

OBKey.s文件中包含原始的OBK二进制文件,即STM32Cube_FW_H5_V1.5.1包中的DA_ConfigWithPassword.obk文件,用户可以根据需要自行替换为合法的OBK文件。

targetApp.s文件中包含目标H563板上运行的测试程序二进制文件,用户也可以自行替换为自己的目标固件代码。

参考工程中的其他文件均为常规代码,此处不再特别说明。

Image
如何通过STM32H5 Bootloader进行固件升

▲图5. OBKey.s

4. 测试

用户可以使用两块NUCLEO-H563开发板验证上述功能,一块作为Host,一块作为Target。两块板的硬件连线示意图如下所示。

Image
如何通过STM32H5 Bootloader进行固件升

▲ 图6. 硬件连接示意图

编译参考工程并将其烧录到Host开发板后,连接串口终端即可查看执行结果,并选择具体的测试项。测试菜单中已提供简单说明,其中x选项用于测试固件下载、Product State切换、OBKEY Provisioning以及Target MCU复位等功能。

当Target端成功运行测试程序后,可以观察到板载LED翻转的测试结果,同时Target端H563的Product State已经改为Closed状态,用户可以使用STM32CubeProgrammer通过DA操作恢复为Open状态。

Image
如何通过STM32H5 Bootloader进行固件升

 图7. 执行结果

5. 小结

结合客户的实际需求,本文给出了相应的解决思路和代码,仅供参考。用户可在参考工程的基础上进一步完善自己的应用方案。

来源:STM32

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

👍 点赞 · 0