[其他ST产品] STM32远程升级基本思路

[复制链接]
799|14
 楼主| 个百zz分点个 发表于 2022-11-28 23:45 | 显示全部楼层 |阅读模式
STM32远程升级基本思路

    开发环境:IAR for ARM 8.30.1
    MCU:STM32F103RCT6
    存储介质:w25q32

1.实现思路

    1.需要一个bootloader程序和APP程序
    2.APP程序通过网络或者串口等方式将要升级的代码写到spiFlash中约定的位置,然后重启
    3.bootloader判断spiFlash中是否有文件需要更新,有就将文件更新到stm32的内部Flash的App区域,然后跳 转到APP,否则直接跳转
————————————————
 楼主| 个百zz分点个 发表于 2022-11-28 23:45 | 显示全部楼层
知识储备
STM32闪存模块组织

stm32F103RCT6属于大容量型产品,ROM:256K,RAM:48K,页大小为2k,闪存分为三个块:

    主存储器:页大小为2K,256K也就是128页
    信息块:分为两个部分:
        系统存储器(存放启动程序代码,ST出厂固化,不可更改,用于ISP编程)
        用户选项字节(Option Bytes,可以用它设置读写保护,硬件看门狗使能啥的)
    闪存存储器接口寄存器:操作stm32内部Flash要用到这些寄存器; 532986384d7a056745.png
 楼主| 个百zz分点个 发表于 2022-11-28 23:47 | 显示全部楼层
启动配置
748666384d7b2ca786.png
● 从主闪存存储器启动:主闪存存储器被映射到启动空间(0x0000 0000)
● 从系统存储器启动:系统存储器被映射到启动空间(0x0000 0000)
● 从内置SRAM启动:只能在0x2000 0000开始的地址区访问SRAM
 楼主| 个百zz分点个 发表于 2022-11-28 23:49 | 显示全部楼层
Bootloader和App的工程设置

    Bootloader和App公用RAM,占用不同ROM空间,16K给Bootloader,240K给App
 楼主| 个百zz分点个 发表于 2022-11-28 23:50 | 显示全部楼层
Bootloader:

    Vector Table Start:0x0800 0000
    ROM:0x0800 0000 ~ 0x0800 4000
    RAM:0x0800 0000 ~ 0x0800 BFFF
    CSTACK: 0x400
    Heap: 0x0
 楼主| 个百zz分点个 发表于 2022-11-28 23:52 | 显示全部楼层
App:

    Vector Table Start:0x0800 4000
    ROM:0x0800 4000 ~ 0x0803 FFFF
    RAM:0x0800 0000 ~ 0x0800 BFFF
    CSTACK: 0x400
    Heap: 0x0
 楼主| 个百zz分点个 发表于 2022-11-28 23:53 | 显示全部楼层
App程序中还要注意到的地方:修改中断向量偏移VECT_TAB_OFFSET,偏移量就是bootloader程序大小
687296384d960444a2.png
 楼主| 个百zz分点个 发表于 2022-11-28 23:53 | 显示全部楼层
Bootloader程序编写

    话不多说,下面就是代码:

    头文件
  1. #define FLASH_MAX_ADDR                      (0x0803FFFFU)  //MCU的Flash最大地址

  2. #ifndef FLASH_PAGE_SIZE
  3.   #define FLASH_PAGE_SIZE                   (0x800U)       //MCU的Flash的页大小,大容量的为2K,其他是1K
  4. #endif

  5. #define APP_BASEADDR                        (0x08004000U)  //升级程序地址


  6. #define APP_PAGE_NUM                        ((FLASH_MAX_ADDR-APP_BASEADDR)/FLASH_PAGE_SIZE+1)

  7. #define SPIFLASHBUF_MAX_LEN                 (0x1000U)  //spi flash最大缓冲4096字节
 楼主| 个百zz分点个 发表于 2022-11-28 23:54 | 显示全部楼层
C文件
  1. void JumpToApplication(void)
  2. {
  3.   typedef  void (*pFunction)(void);
  4.   pFunction Jump_To_Application;
  5.   u32 JumpAddress;   
  6.   
  7.   /* Test if user code is programmed starting from address "ApplicationAddress" */
  8.   if (((*(__IO uint32_t*)APP_BASEADDR) & 0x2FFE0000 ) == 0x20000000)
  9.   {
  10.    
  11.     DBG_LOG("----[Boot]Jump to Application!!!\r\n");
  12.     LED_ALL_OFF();
  13.     __disable_irq();
  14.    
  15.     /* Jump to user application */
  16.     JumpAddress = *(__IO uint32_t*) (APP_BASEADDR + 4);
  17.     Jump_To_Application = (pFunction) JumpAddress;
  18.     /* Initialize user application's Stack Pointer */
  19.     __set_MSP(*(__IO uint32_t*) APP_BASEADDR);
  20.     Jump_To_Application();
  21.   }
  22.   else
  23.   {
  24.     DBG_LOG("----[Boot]Application Address is ERROR!!!\r\n");
  25.     LED_ALL_ON();
  26.   }   
  27. }

  28. union {
  29.   u32 stm32[SPIFLASHBUF_MAX_LEN/4];
  30.   u8  spi[SPIFLASHBUF_MAX_LEN];
  31. }Flash;

  32. void Boot_Initializes(void)
  33. {

  34.   u16 i,j;
  35.   
  36.   u32 update_file_mark;
  37.   
  38.   u32 writeFlashData;

  39.   HAL_StatusTypeDef status;
  40.   
  41.   FLASH_EraseInitTypeDef f;
  42.   
  43.         f.TypeErase = FLASH_TYPEERASE_PAGES;
  44.         f.PageAddress = APP_BASEADDR;
  45.         f.NbPages = APP_PAGE_NUM;

  46.   //1.判断spi flash DFU区是否有文件需要升级
  47.   SFlash_Read(SECTOR_ADDR(SECTOR_DFU_START),(u8 *)&update_file_mark,4);
  48.   
  49.   if(update_file_mark == 0xFFFFFFFF){
  50.     DBG_LOG("[Boot] No Firmware Need to Update.");
  51.     LED_ON(ERR);
  52.     JumpToApplication();
  53.     return;
  54.   }
  55.   //有文件需要升级
  56.   DBG_LOG("[Boot] New Firmware Exist! Update Beginning...");
  57.   
  58.   //2.Flash解锁
  59.   status = HAL_FLASH_Unlock();
  60.   
  61.   if(status != HAL_OK){
  62.     DBG_LOG("[Boot] FLASH Unlock Failed.");
  63.     LED_ON(ERR);
  64.     return;
  65.   }
  66.   DBG_LOG("[Boot] FLASH Unlock Ok.");
  67.   
  68.   DBG_LOG("[Boot] Ready to Erase Flash ...");
  69.   //3.擦除Flash
  70.   status = HAL_FLASHEx_Erase(&f,&writeFlashData);
  71.   
  72.   if(status != HAL_OK){
  73.     DBG_LOG("[Boot] Flash Erase Failed.");
  74.     LED_ON(ERR);
  75.     return;
  76.   }
  77.   DBG_LOG("[Boot] Flash Erase OK.");
  78.   
  79.   
  80.   //4.从SPIFlash中读出数据然后copy到内部Flash中
  81.   for(i = 0;i < (APP_PAGE_NUM / 2);i++){
  82.    
  83.     SFlash_Read(SECTOR_ADDR(SECTOR_DFU_START) + SPIFLASHBUF_MAX_LEN*i, Flash.spi, SPIFLASHBUF_MAX_LEN);
  84.    
  85.     DBG_LOG("[Boot] Write Flash Progress:%d%%",(i*100/(APP_PAGE_NUM / 2)) );
  86.    
  87.     LED_TOGGLE(WIFI);
  88.    
  89.     for(j = 0;j < (SPIFLASHBUF_MAX_LEN/4);j++){
  90.       //注意基地址是在变化的
  91.       HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, APP_BASEADDR+SPIFLASHBUF_MAX_LEN*i+4*j, Flash.stm32[j]);
  92.     }   
  93.   }
  94.   
  95.   DBG_LOG("[Boot] Write Flash Progress:100%%");
  96.   DBG_LOG("[Boot] Program Complete!!!");
  97.   
  98.   //5.Flash上锁
  99.   HAL_FLASH_Lock();  
  100.   
  101.   //6.跳转到用户程序区
  102.   JumpToApplication();
  103.   
  104. }


claretttt 发表于 2022-12-14 11:43 | 显示全部楼层
这个不是有实现的方式吗?              
maudlu 发表于 2022-12-14 11:52 | 显示全部楼层
需要修改BootLoader吗?
eefas 发表于 2022-12-17 19:41 | 显示全部楼层
代码是否可以通过485升级?              
AloneKaven 发表于 2022-12-18 18:28 | 显示全部楼层
修改boot loader就可以用想要的的方式升级了
jkl21 发表于 2022-12-18 23:07 | 显示全部楼层
远程升级的代码怎么校验呢?              
小小蚂蚁举千斤 发表于 2022-12-20 09:59 | 显示全部楼层
楼主的意思是修改bootloader就可以远程升级?远程能否详细讲解一下?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

53

主题

679

帖子

0

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