天天看点

STM32H750 iap固件升级

之前写STM32F4的IAP升级的时候就想写篇博客记录一下,但因为懒就一直没有实施,这次项目用到了STM32H750的IAP升级,所以就趁这次机会记录一下H7的IAP算是补上了。

  1. STM32H750芯片概述

    H750芯片内部存储空间只有128KByte,也就是1个扇区,其工作频率最高可达400MHz,并且配有QSPI与外部FLASH通信,可以直接将内存地址映射到外部FLASH,也就是说可以像读取内部FLASH直接取地址那样去读取外设FLASH(如*(u32*)0x9000 0000)。

    STM32H750 iap固件升级
  2. 情况分析

    IAP升级主要由跳转处理程序和主程序构成,跳转程序我们称为Bootloader,主程序称为APP。假设APP主程序大小大于128K,也就是说单靠内部FLASH是不够运行的,所以加一个外部FLASH采用内部+外部的方式运行APP,把关键代码运行在内部,剩余的运行在外部。这样运行APP没问题了,那要做IAP升级的话又是什么情况呢?

    要让程序运行在外部FLASH,必须把接口配置为QSPI的内存映射模式,但从参考手册中看到这么一句话:

    STM32H750 iap固件升级
    也就是说程序运行过程中对QSPI FLASH只能读不能写,H750内部FLASH只有一个扇区,我们知道存储器的擦除是以扇区为单位的,写入内部的话运行在内部的程序也会被擦除掉,所以内部也不能写。那我们升级过程中接收到的app程序要存到哪里呢?那只能是加多一块外部FLASH了。(有更好的想法欢迎评论区讨论!)
  3. IAP设计思路

    综上所述这次H750的IAP升级用到了两片1M的外部FLASH存储芯片(w25q80)。一片主要配合内部FLASH运行APP程序,称为QSPI FLASH。另外一片主要用来存储数据和程序,称为SPI FALSH。128K的内部FLASH分为两段,前20K用来运行Bootloader1,剩下的运行APP的内部程序段(APP1-1)。QSPI FLASH也分成两段,前20K用来存放(这里不是运行)Bootloader2,剩下的运行APP的外部程序段(APP1-2)。上面加粗的字段在下面的内存分配图和流程图中会用到,要看懂流程图还得知道这些字段代表什么东西。

各个存储器的使用分配情况,如下图所示:

STM32H750 iap固件升级

其中Bootloader1负责将待更新的app外部程序段(app2-2)从 SPI FLASH 拷贝到 QSPI FLASH的APP1-2中,并且将Bootloader1读出拷贝到SPI FLASH的 bootloader1备份 中。Bootloader2负责将待更新的app内部程序段(app2-1)从 SPI FLASH 拷贝到内部FLASH的APP1-1中,同时将bootloader1备份拷贝回内部FLASH的Bootloader1中。如下图:

STM32H750 iap固件升级

分配好内存之后就可以设计程序了,程序分为四个部分,流程图如下:

STM32H750 iap固件升级

其中前两个,烧录程序和boot1需要用烧录器(如ST-Link/V2)烧录到单片机中。

首先左边第一个烧录程序:

是用来将Bootloader2和第一个APP程序烧录进对应的外部FLASH存储区的,这里需要用到另外一个工具(点击进我博客下载)将APP和Bootloader2的bin文件转换成c语言数组形式,然后在程序中定义成数组,接着就是把数组里的数据写进对应存储区了,最后设定一个更新标志写进外部SPI FLASH的必要状态标志中,以便Bootloader1中读取判断。芯片的SRAM大小必须大于所有定义数组的总和,不然无法采用这种方法。

第二个程序BOOT1:

运行在内部FLASH中,这个程序的两个功能前面说过:第一个将app外部程序段(app2-2)从 SPI FLASH 拷贝到 QSPI FLASH的APP1-2中,第二个功能将Bootloader1读出拷贝到SPI FLASH的 bootloader1备份 中,最后读取存放在QSPI FLASH中的Bootloader2到SRAM(定义的数组默认地址为SRAM)并跳转运行。需要说明一下,由于单片机每次断电或复位重启后都是从内部FLASH的地址0x0800 0000处开始运行的,意味着单片机每次上电或重启后都会先运行Bootloader1,所以设定了一个更新标志是为了防止每次上电都擦除和读写FLASH,毕竟FLASH都是有擦写寿命的,设定更新标志后,bootloader1只会在第一次运行的时候执行擦写操作,app没有更新的情况下都不会执行擦写操作了。

第三个程序BOOT2:

前面说到这个程序只是存放(不是运行)在QSPI FLASH,理论上来说运行中的程序直接跳转到QSPI FLASH运行应该是可以实现的,但我在测试过程一直没有成功,找不到原因所以改了方案,把BOOT2拷贝到SRAM运行了。BOOT2主要就是往内部FLASH写数据了,写完后直接跳转到APP1-1(0x0800 5000)运行主程序。

第四个程序APP中的接收处理:

出于程序的安全考虑,需要上位机下发APP固件之前先发送APP的长度,网口接收到数据长度和数据之后进行长度校验,校验成功才置位更新标记并重启(软复位函数:NVIC_SystemReset())。重启后单片机又会从BOOT1(0x0800 0000)处开始运行,再次执行前面的步骤完成更新!

继续阅读