[应用相关] [分享] STM32在线升级(IAP)超详细图解 及 需要注意的问题

[复制链接]
 楼主| 一点点0321 发表于 2020-11-29 20:15 | 显示全部楼层
在大程序的main函数的执行过程中,如果CPU得到一个中断请求,由于我们设置了中断向量表偏移量为N+M,因此PC指针被强制跳转到0x08000004+N+M处的中断向量表中得到相应的中断函数地址,再跳转到相应新的中断服务函数,执行结束后返回到main函数中来。
 楼主| 一点点0321 发表于 2020-11-29 20:16 | 显示全部楼层
需要注意的是,复位中断比较特殊。产生复位后,PC的值会被硬件强制置为0x08000004。因为,在发生复位后,负责中断向量偏移的寄存器VTOR变为了0,因此,复位后的中断就变为了0x08000004。而其他中断发生时,VTOR为已经设置好的终端向量表偏移
 楼主| 一点点0321 发表于 2020-11-29 20:16 | 显示全部楼层
程序实现
  有了上面的介绍,实现就比较简单了!其实我有设计了一套适用于全部STM32芯片的IAP模板,但是属于公司产品,不方便对外公布!简单说几个重点:
 楼主| 一点点0321 发表于 2020-11-29 20:17 | 显示全部楼层
使用 分散加载文件 实现起来会比较方便
对于没有中断向量表偏移寄存器的MCU(主要是Cortex-M0核),一般采用将中断向量表复制到指定位置的内存中的方式实现:
 楼主| 一点点0321 发表于 2020-11-29 20:18 | 显示全部楼层
使用分散加载文件在内存中指定一块区域:
  1. #if   (defined ( __CC_ARM ))
  2.           __IO uint32_t VectorTable[48] __attribute__((section("SECTION_APP_VECTOR")));
  3.         #elif (defined (__ICCARM__))
  4.         #pragma location = 0x20000000
  5.           __no_init __IO uint32_t VectorTable[48];
  6.         #elif defined   (  __GNUC__  )
  7.           __IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
  8.         #elif defined ( __TASKING__ )
  9.           __IO uint32_t VectorTable[48] __at(0x20000000);
  10.         #endif
 楼主| 一点点0321 发表于 2020-11-29 20:19 | 显示全部楼层
2.将APP的终端向量表复制到以上位置,设置中断向量表重映射
  1. static void SetVectorTable(void)
  2. {
  3.         int i;

  4.         /*!< At this stage the microcontroller clock setting is already configured,
  5.         this is done through SystemInit() function which is called from startup
  6.         file (startup_stm32f0xx.s) before to branch to application main.
  7.         To reconfigure the default setting of SystemInit() function, refer to
  8.         system_stm32f0xx.c file
  9.         */

  10.         /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/  
  11.         /* Copy the vector table from the Flash (mapped at the base of the application load address 0x08003000) to the base address of the SRAM at 0x20000000. */
  12.         for(i = 0; i < 48; i++)
  13.         {
  14.                 VectorTable[i] = *(__IO uint32_t*)(APP_SPACE_ADDR + (i<<2));
  15.         }

  16.         /* Enable the SYSCFG peripheral clock */
  17.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);        /* 注意:ST官方例程使用 RCC_APB2PeriphResetCmd是不对的 */
  18.         /* Remap SRAM at 0x00000000 */
  19.         SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
  20. }
 楼主| 一点点0321 发表于 2020-11-29 20:19 | 显示全部楼层
3.在由 IAP 跳转到 APP 时,一定注意把 IAP 中开启的外设全部关闭,否则在刚进入 APP中时,如果产生中断将导致死机等问题。 包括 SysTic 中断!!!包括 SysTic 中断!!!包括 SysTic 中断!!!这里可以做测试:
 楼主| 一点点0321 发表于 2020-11-29 20:20 | 显示全部楼层
1.测试一:IAP 中开启串口,然后用上位机不停的发送数据,在发送数据过程中执行 IAP 跳转 APP
 楼主| 一点点0321 发表于 2020-11-29 20:21 | 显示全部楼层
2.将 SysTick 中断 配置时间很短(微秒级别),当程序跳转到 APP 后,会出现 先产生 SysTick 中断,然后才会到 main 函数。此时如果 SysTick 中断中有相关代码,将导致出现错误!
taobaofarmer 发表于 2020-11-29 20:25 | 显示全部楼层
这个帖子写个标题只为了吸睛?
elephant00 发表于 2020-11-30 09:16 | 显示全部楼层
楼主一点点的分享很详细 啊,楼主辛苦了
taobaofarmer 发表于 2020-11-30 09:28 | 显示全部楼层
很好的帖子,能不能做成一个PDF文档给大家分享?
playxzy 发表于 2020-11-30 10:48 | 显示全部楼层
有没有PDF,可以发一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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