发新帖我要提问
12
返回列表
打印
[应用相关]

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

[复制链接]
楼主: 一点点0321
手机看帖
扫描二维码
随时随地手机跟帖
21
一点点0321|  楼主 | 2020-11-29 20:15 | 只看该作者 回帖奖励 |倒序浏览
在大程序的main函数的执行过程中,如果CPU得到一个中断请求,由于我们设置了中断向量表偏移量为N+M,因此PC指针被强制跳转到0x08000004+N+M处的中断向量表中得到相应的中断函数地址,再跳转到相应新的中断服务函数,执行结束后返回到main函数中来。

使用特权

评论回复
22
一点点0321|  楼主 | 2020-11-29 20:16 | 只看该作者
需要注意的是,复位中断比较特殊。产生复位后,PC的值会被硬件强制置为0x08000004。因为,在发生复位后,负责中断向量偏移的寄存器VTOR变为了0,因此,复位后的中断就变为了0x08000004。而其他中断发生时,VTOR为已经设置好的终端向量表偏移

使用特权

评论回复
23
一点点0321|  楼主 | 2020-11-29 20:16 | 只看该作者
程序实现
  有了上面的介绍,实现就比较简单了!其实我有设计了一套适用于全部STM32芯片的IAP模板,但是属于公司产品,不方便对外公布!简单说几个重点:

使用特权

评论回复
24
一点点0321|  楼主 | 2020-11-29 20:17 | 只看该作者
使用 分散加载文件 实现起来会比较方便
对于没有中断向量表偏移寄存器的MCU(主要是Cortex-M0核),一般采用将中断向量表复制到指定位置的内存中的方式实现:

使用特权

评论回复
25
一点点0321|  楼主 | 2020-11-29 20:18 | 只看该作者
使用分散加载文件在内存中指定一块区域:
#if   (defined ( __CC_ARM ))
          __IO uint32_t VectorTable[48] __attribute__((section("SECTION_APP_VECTOR")));
        #elif (defined (__ICCARM__))
        #pragma location = 0x20000000
          __no_init __IO uint32_t VectorTable[48];
        #elif defined   (  __GNUC__  )
          __IO uint32_t VectorTable[48] __attribute__((section(".RAMVectorTable")));
        #elif defined ( __TASKING__ )
          __IO uint32_t VectorTable[48] __at(0x20000000);
        #endif

使用特权

评论回复
26
一点点0321|  楼主 | 2020-11-29 20:19 | 只看该作者
2.将APP的终端向量表复制到以上位置,设置中断向量表重映射
static void SetVectorTable(void)
{
        int i;

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

        /* Relocate by software the vector table to the internal SRAM at 0x20000000 ***/  
        /* 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. */
        for(i = 0; i < 48; i++)
        {
                VectorTable[i] = *(__IO uint32_t*)(APP_SPACE_ADDR + (i<<2));
        }

        /* Enable the SYSCFG peripheral clock */
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);        /* 注意:ST官方例程使用 RCC_APB2PeriphResetCmd是不对的 */
        /* Remap SRAM at 0x00000000 */
        SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
}

使用特权

评论回复
27
一点点0321|  楼主 | 2020-11-29 20:19 | 只看该作者
3.在由 IAP 跳转到 APP 时,一定注意把 IAP 中开启的外设全部关闭,否则在刚进入 APP中时,如果产生中断将导致死机等问题。 包括 SysTic 中断!!!包括 SysTic 中断!!!包括 SysTic 中断!!!这里可以做测试:

使用特权

评论回复
28
一点点0321|  楼主 | 2020-11-29 20:20 | 只看该作者
1.测试一:IAP 中开启串口,然后用上位机不停的发送数据,在发送数据过程中执行 IAP 跳转 APP

使用特权

评论回复
29
一点点0321|  楼主 | 2020-11-29 20:21 | 只看该作者
2.将 SysTick 中断 配置时间很短(微秒级别),当程序跳转到 APP 后,会出现 先产生 SysTick 中断,然后才会到 main 函数。此时如果 SysTick 中断中有相关代码,将导致出现错误!

使用特权

评论回复
30
taobaofarmer| | 2020-11-29 20:25 | 只看该作者
这个帖子写个标题只为了吸睛?

使用特权

评论回复
31
elephant00| | 2020-11-30 09:16 | 只看该作者
楼主一点点的分享很详细 啊,楼主辛苦了

使用特权

评论回复
32
taobaofarmer| | 2020-11-30 09:28 | 只看该作者
很好的帖子,能不能做成一个PDF文档给大家分享?

使用特权

评论回复
33
playxzy| | 2020-11-30 10:48 | 只看该作者
有没有PDF,可以发一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则