IAP-Bootloader:基于STM32F407 STM32CubeMX的按钮式Bootloader程序与APP程序切换

一、前言


1.1、IAP与ISP

bootloader一般分为两种:

1、ISP – 使用ST芯片自带的bootloader程序实现APP程序的刷写,其优势是简单,可靠。

2、IAP – 自己编写一个bootlader实现APP程序的刷写,其优势是自定义,灵活性强。可以通过任意的通讯接口实现远程升级。

ISP的bootloader实战,可以参考之前我的以下文章:

bootloader | 基于STM32F407 – 使用STM32Cubeprogrammer的USB DFU进行固件烧写

bootloader | 基于STM32F407 – 使用STM32Cubeprogrammer的UART进行固件烧写

在学习IAP时,找到一些不错的资料:

【实战技能】单片机bootloader的CANFD,I2C,SPI和串口方式更新APP视频教程(2022-08-01)

BSP视频教程第17期:单片机bootloader专题,启动,跳转配置和调试下载的各种用法(2022-06-10)

【不是问题的问题】为什么STM32的Flash地址要设置到0x08000000

下面文章是初学IAP的重点,文章是基于标准库解决问题,在HAL库上原理一样,只是处理方法改一下。(HAL库没有函数NVIC_SetVectorTable)

从启动程序(BootLoader)跳转到指定地址时(APP)出现问题的解决方法

文章后见会介绍如何在HAL库上处理这个问题(system_stm32f4xx.c文件),毕竟现在使用标准库的人比较少,且ST官方也不建议使用标准库了。

IAP的难点在于Bootloader跳转APP,有如下几点需要弄明白的:

  • .map文件的阅读
  • 中断向量表
  • STM32的启动流程
  • flash内存的分配
  • 1.2、本次实验的目的

    将自己编写的bootloader程序烧写进STM32芯片的FLASH地址0x08000000的起始位置,接着将APP程序烧写进STM32芯片的FLASH地址0x08010000起始的地址。

  • 点击按钮KEY1,bootloader程序切换至APP程序运行。
  • 点击按钮KEY2,APP程序切换至bootloader程序运行。

    一共有两个程序,APP与BOOT(bootloader程序)。

    学会bootloader与APP程序互相跳转的程序后,接着可以使用串口,CAN,SPI,I2C,网口等通讯接口升级APP程序了。
  • 工程分享:

    链接:https://pan.baidu.com/s/1ZeSxh10BbqqPjarWMkDbfQ?pwd=f2zz

    提取码:f2zz

    二、STM32CubeMX


    STM32CubeMX配置初始的工程的步骤我就省去了,本例程只使用了简单的GPIO输出与GPIO读取,并没有复杂的外设。将百度云盘分享的工程下载下来直接查看配置即可。

    三、MDK的设置


    3.1、Bootloader工程

    Flash起始地址: 0x8000000,其大小是0x10000(65536/1024 = 64K)

    最后修改下载算法,将BOOT程序的下载地址限制在0x08000000 – 0x0800FFFF

    3.2、APP工程


    最后修改下载算法,将BOOT程序的下载地址限制在0x08010000 – 0x0803FFFF

    四、代码


    4.1、Bootloader工程

    4.1.1、main.c



    函数JumpToBootloader()是从安富莱那里直接拷贝过来使用的,比其他嵌入式厂家要专业。
    我的APP程序是从FLASH内存的0x08010000开始,这个按照自己的内存分配修改一下即可。

    4.1.2、system_stm32f4xx.c

    这里非常重要!这里非常重要!这里非常重要!重要的事情说三遍!!!!!!
    这个代码就是修改程序的中断向量表从内存FLASH哪里取出来,并初始化。bootloader程序的中断向量表在0x08000004里。后面会介绍为什么我知道bootloader程序的中断向量表是在内存0x08000004里边。


    编译一下工程:

    4.2、APP工程

    4.2.1、main.c



    4.2.2、system_stm32f4xx.c



    编译一下工程:

    五、map文件确认程序flash的位置与中断向量表的位置

    Keil工程的map文件如何打开,可以参考:
    Keil | 解决Keil双击工程名无法打开.map的问题

    5.1、Bootloader工程的map文件

    5.1.1、确认flash的位置

    5.1.2、确认中断向量表的位置

    5.2、APP工程

    5.2.1、确认flash的位置

    5.2.2、确认中断向量表的位置


    从两个工程的.map文件看来,flash与中断向量表的设置都是在预期。

    六、下载两个程序到板子上


    直接用MDK把两个工程都烧写进去,两个工程的FLASH地址设置不一样,所以不会互相影响。

    下载bootloader程序。

    下载APP程序。

    七、观察板子


    下载完两个程序进去后,板子重新上电。

    首先,LED1在闪烁,LED2与LED3都是熄灭。表示正在运行bootlader程序。接着,按下KEY1。

    按下KEY1后,LED1与LED2在闪烁,LED3常亮,表示此时正在运行的是APP程序。

    当我们按下KEY2后,LED1在闪烁,LED2与LED3都是熄灭的。表示此时又返回运行bootlader程序了。

    至此,实验成功!!!!

    八、细节补充


    8.1、为什么需要修改system_stm32f4xx.c的代码?

    原因是程序跳转之后,还需要另外告诉程序中断向量表也需要跳转。比如bootloader跳转APP程序后,此时的中断向量表也需要指向APP程序的中断向量表,否则无法产生中断。

    bootloader程序与APP程序都有自己的中断向量表。

    修改system_stm32f4xx.c就是为了达到这个目的。实际上,从system_stm32f4xx.c上看,HAL也准备好了代码给我实现中断向量表的重新设置。

    看下面代码:

    VECT_TAB_BASE_ADDRESS被谁调用?往下看。

    VECT_TAB_BASE_ADDRESS被函数SystemInit()调用了。

    OK…那谁调用了函数SystemInit()?从下图看到,从STM32F407的启动文件找到,Reset_handler中断回调调用了SyetemInit( ),接着进入main()函数开始运行。

    梳理完了,大概是这样的。。

    8.2、不修改system_stm32f4xx.c的代码可以吗?

    当然可以啊,我们修改system_stm32f4xx.c就是为了运行这个代码:

    那么,我们在main()函数写入这个代码也可以的,如下图所示:
    bootloader工程:

    APP工程:

    物联沃分享整理
    物联沃-IOTWORD物联网 » IAP-Bootloader:基于STM32F407 STM32CubeMX的按钮式Bootloader程序与APP程序切换

    发表评论