[STM32F4] 基于单片机的IAP,bootloader常用的方法

[复制链接]
14153|7
 楼主| 穿西装的强子 发表于 2024-4-8 11:23 | 显示全部楼层 |阅读模式
本帖最后由 穿西装的强子 于 2024-4-8 11:45 编辑

#申请原创# 以STM32F407VET6为例,片上FLASH共有1MBytes大小,分为12个扇区,按datasheet图所示,Main memory
804046613602a3af16.png
升级主要流程
按不同需求分为几个部分
1.bootloader程序
2.APP程序
3.升级缓存
4.备份(可选)
5.数据存储

一、BootLoader程序及流程
流程图如下:
48513661362c5cb501.png
FLASH分区
以标黄的部分作为自定义的FLASH分区
1.bootloader程序区
2.APP程序区
3.升级缓存区
4.备份区(可选)
5.数据存储区
以上五个部分进行分区
a)bootloader一般10~20Kbytes大小,以64K大小为例,使用扇区0~3;
b)APP程序区,根据不同的代码有不同的大小,若需要备份区,则代码根据剩余的大小平均分3份,例如(1024-32)/3 =330.6666666666667,但是从扇区5开始都是128Kbytes的大小,所以我们暂定256Kbytes大小,那么从扇区5~扇区6为APP区;
c)升级缓存区,该区域是将升级的文件接收到之后放置在该区域,所以该区域的大小是与APP程序区的大小一致,因此分配扇区7~扇区8;
d)备份区,该区域作为软件备份使用,将APP程序备份在此区域,若需要恢复出厂设置或者回退版本则需要将此处数据复制到APP区即可,因此分配扇区9~扇区10;
e)数据存储区,该区域作为自定义数据存储和升级数据的存储区域,一般不会太大,使用扇区4或者扇区11~扇区12均可;
不同的芯片不同的FLASH大小均可按此种方式进行分配;
BootLoader升级代码流程
一、检测是否有APP标志或者找到APP地址上是否有数据
  1. void DevUpdate_Handle(void)
  2. {
  3.         if( gfirmbuff->gProtocolFirmware.App_flag == TRUE || (*(__IO uint32_t *)FLASH_APP_ADDR) != 0xFFFFFFFF)
  4.         {
  5.                 if( gfirmbuff->gProtocolFirmware.Update_active == Active_reload ) // 如果有回退标记
  6.                 {
  7.                         if(  gfirmbuff->gProtocolFirmware.Backoff_flag == TRUE)                // 如果备份区有数据则回退,否则正常进入系统
  8.                         {
  9.                                 DevUpdate_Realod();
  10.                         }
  11.                         else
  12.                                 gfirmbuff->gProtocolFirmware.Update_active = Active_none;
  13.                 }
  14.                 else if( gfirmbuff->gProtocolFirmware.Update_active == Active_update) // 如果有更新标记
  15.                 {
  16.                         DevUpdate_Update();
  17.                 }
  18.                 else if( gfirmbuff->gProtocolFirmware.Update_active == Active_none)        // 无更新,无回退并且有APP则直接进入系统
  19.                 {
  20.                         DevUpdate_JumpToApp();
  21.                 }
  22.         }
  23. }
二、更新数据到APP地址
  1. void DevUpdate_Update(void)
  2. {
  3.         INT32U i = 0;
  4.         INT32U buff[10];
  5.         INT32U buff_2;
  6.         DrvFlash_ReadWords(FLASH_DATA_ADDR,&buff_2,1);
  7.         if( buff_2 != 0xFFFFFFFF)
  8.         {
  9.                 // 将缓存数据复制到FLASH内
  10.                 for(i = 0; i < APP_ROM_SIZE/40; i++)
  11.                 {
  12.                         DrvFlash_ReadWords(FLASH_DATA_ADDR+i*40,buff,10);
  13.                         DrvFlash_WriteWords(FLASH_APP_ADDR+i*40,buff,10);
  14.                 }
  15.                
  16.                 gfirmbuff->gProtocolFirmware.firmwaresize = 0;
  17.                 gfirmbuff->gProtocolFirmware.Update_active = Active_none;
  18.                 DevProtocol_SaveUpdateParameter();                                                                // 记录数据
  19.         }
  20.         else
  21.                 gfirmbuff->gProtocolFirmware.Update_active = Active_none;
  22. }
三、跳转到APP
  1. void DevUpdate_JumpToApp(void)
  2. {
  3.         DevProtocol_SaveUpdateParameter();        
  4.         DrvTimer_Disable(Timer2);
  5.         DrvUart_Disable(UartPort1);
  6.         __disable_irq();
  7.                
  8.         /* Test if user code is programmed starting from address "ApplicationAddress" */

  9.         if (((*(__IO uint32_t *)FLASH_APP_ADDR) & 0x2FFE0000) == 0x20000000) //检查栈顶地址是否合法
  10.         {
  11.                 /* Jump to user application */
  12.                 JumpAddress = *(__IO uint32_t *)(FLASH_APP_ADDR + 4);
  13.                 Jump_To_Application = (pFunction)JumpAddress;

  14.                 /* Initialize user application's Stack Pointer */
  15.                 __set_MSP(*(__IO uint32_t *)FLASH_APP_ADDR);                        
  16.                
  17.                 //Jump to APP
  18.                 Jump_To_Application();
  19.         }
  20. }
bin文件通过串口或者其它通信,将bin转换为16进制数据,将数据发送到缓存区内,通过校验后,将缓存区的数据复制到APP区,跳转到APP区的起始地址,再将msp设置到APP区的起始地址,整个流程就算完成;

二、APP程序
APP只需要处/3个地方
1、起始地址和大小的配置
35711661367bd9e7ce.png
2、生成BIN文件
35556661367d53565d.png
3、设置FLASH的偏移
39286661368018083c.png
这样便完成整个IAP升级的流程。







评论

编辑推荐:奖励200家园币!  发表于 2024-4-16 15:39
EmmaTT 发表于 2024-4-8 14:47 来自手机 | 显示全部楼层
更改起始位置有什么作用啊
 楼主| 穿西装的强子 发表于 2024-4-8 15:20 | 显示全部楼层
EmmaTT 发表于 2024-4-8 14:47
更改起始位置有什么作用啊

哪个地方呢?如果是APP的话,因为起始地址如果是8000000的话就会把boot程序擦除
18929501591 发表于 2024-4-8 16:22 | 显示全部楼层
wangwu1976@ 发表于 2024-4-17 08:55 | 显示全部楼层
好贴,顶一个。
jalzhang 发表于 2024-4-22 13:14 | 显示全部楼层
学习了 大牛
ColeYao 发表于 2024-4-23 08:34 | 显示全部楼层
第三步 跳转到APP,如果BootLoader有FreeRTOS在运行的话,不一定能正常跳转!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

63

主题

264

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部