STM32的程序升级

IAP基础参考http://www.eeworld.com.cn/mcu/2018/ic-news112042038.html

https://blog.csdn.net/tq384998430/article/details/81010002

ISP,IAP,DFU:

      ISP:是为了解决烧写MCU必须将芯片从目标板拆下来才能烧写的问题;ISP下每家芯片内部的的bootload 都不同,不通用。bootloader在芯片复位(或者上电)时,会优先于用户自己的代码启动。这段代码会首先检测芯片的指定引脚上有没有特定的信号,如果没有,则跳入用户程序执行。否则就按照bootloader特定的通信协议,与计算机进行握手,并最终触发计算机将新的程序通过通用接口(如串口)传送到芯片。

  IAP:芯片内部有厂家的固定boot,但bootloader需要在固定引脚,通过串口,以固定的协议传送程序。如果你对这个过程的任何一点不满意,那你就要自定义bootloader、

      DFU:也就是usb boot,usb在单片机上和pc有两种配合方法:

  • VCP模式:PC端通过安装VCP usb drive和MCU的APP进行业务通信
  • DFU模式:PC端通过安装DFU usb drive和MCU的bootload(自定义)进行通信。此时进入boot有两种模式:reset复位或者电源掉电的硬件方式;或者MCU解析PC发送的内容后进行的软复位方式。

程序升级的文件:HEX、bin

HEX文件:特点:适合ISP,不适合FOTA(因为HEX开始有ISP升级的头字段);KEIL中的生成:Options -> Output 下勾选Create HEX File

BIN文件:真正升级的二进制文件字节流,尺寸小,适合FOTA;KEIL中生成方法:User选项卡下面的 After Build/Rebuild 设置并打钩:fromelf --bin !L -o .\BIN\FOTA.bin。

程序升级过程:

  • 在APP运行过程中,如果条件触发(按键按下、串口收到指定命令或者字符,从指定存储位置读取的版本号比当前新),此时APP会从指定的源头(/USB/SD/网页服务器)把APP_new.bin文件一次性或者分包拷贝到MCU的备份区(MCU的flash备份区、外部FLASH),置位需要更新程序的标志到非易失存储位置(RTC的BKP区、MCU的EEPROM/FLASH区、外部的eerom/flash区),然后让程序跳转到IAP程序中(复位跳转、直接跳转);
  • 在IAP程序中,若有升级标志则先擦除APP_RUN—FLASH,然后将备份区的内容拷贝到此运行区并做好校验,然后继续跳转会运行程序区(复位、直接跳转);若无升级标志或者过一定时间无操作则跳会APP运行程序区;
  • 运行APP程序(开始注意NVIC需要重定向NVIC_SetVectorTable(NVIC_VectTab_FLASH,APP_StartAddr),并继续监控是否需要升级。

简而言之:IAP要实现2个功能:跳转和更新程序

  1. 规划好boot程序和APP程序的起始地址;分别编写2个工程的程序,注意APP程序需要NVIC重定向NVIC_SetVectorTable(NVIC_VectTab_FLASH,APP_StartAddr)
  2. APP程序根据触发条件判断是否要升级,需要的话将新程序拷贝到一个存储位置,存储升级标记;并强制程序跳转到boot程序位置(也可以软重启)
  3. 进入BOOT程序后,如果有更新标记则擦除app的flash区域,并将新存储的程序写到app的flash区域,校验成功后取消更新标记,并强制跳转到APP区域。通过__asm("B APP_StartAddr +4")或者指针跳转实现跳转。      
void (*p)(void) = (void (*)(void))(*((int*)(APP_StartAddr +4)));
 p();
__set_MSP(*(uint32_t*) ApplicationAddress);
View Code
  1. 注意flash的操作先FLASH_Unlock,再FLASH_ClearFlag,操作完之后FLASH_Lock。
  2. 擦除可以用winhex删除制定区域,HEX转BIN的不一定能直接使用主机检查其开始地址是否是APP_StartAddr

FLASH的分区:

分2个区(IAP+APP)+外存(usb/sd/):此种没有老程序的备份,万一升级失败就只能冲刷老程序

分3个区(IAP+APP_Run+APP_BKP备份缓存):这种比较浪费MCU的flash,成本上没有利用外存经济。

分4个区IAP+APP_Run+APP_MAIN+APP_STATIC:其中APP_STATIC为参数存储区,

程序升级重点是要解决升级过程中升级失败(升级过程中关中断,若串口中断接收关其它中断)或者分包传输(没有大缓存)分包错误的处理;无线升级要考虑到客户的方便性、配合度、安全性、大批量升级的效率问题

BOOTloader分类:单独开发、UBOOT/MCU厂商或者中间件厂商rtt提供的BOOT

 APP.hex与boo.hext的合并烧录:合并工具

一 非无线接口:(串口、SPI/I2C/CAN/485/USB/SD):

1.0 :

1.x:程序的合并烧写:通过JLINK将IAP和app的烧写文件进行合并成一个烧写文件,大量MCU批量烧写可以利用这种方法。

二 无线接口(WLAN/WIFI/蓝牙/GPRS):

 STM32G47x 双 Bank 模式下在线升级

 STM32G47x 的 Flash 可以工作在双 bank 模式,在该模式下对 FLASH 的操作支持RWW(Read-While-Write),即在 Bank1 中可以对 Bank2 进行操作而不影响当前 Bank1 中的应用程序的运行,反之亦然.

通过设置标志位 BFB2 来决定从哪一个 Bank 启动: 

BFB2 = 0,MCU 双 Bank 启动禁用,从 Bank1 启动运行;

BFB2 = 1,MCU 双 Bank 启动使能,从 Bank2 启动运行,若是 Bank2 中无正常程序,则检测 Bank1 中是否有正常程序,若有则运行 Bank1 中的程序,若无则跳转到系统 Bootloader 运行(详见 AN2606 对应说明)。 

FB_MODE 反映了 Bank 的地址映射,双 Bank 的地址映射方式如下:

FB_MODE= 0 时,Bank1 的起始地址为 0x08000000,Bank2 的起始地址为

0x08040000;FB_MODE= 1 时,Bank1 的起始地址为 0x08040000,Bank2 的起始地址为0x08000000;

注意:程序始终是从ox08000000开始,只不过通过地址重映射的方式,将不同的 Bank 起始地址指定到 0x08000000

 

posted on 2019-07-02 20:01  杰瑞鼠  阅读(2566)  评论(0编辑  收藏  举报