stm32IAP代码升级小结

来源:互联网 发布:js格式化日期时间 编辑:程序博客网 时间:2024/04/28 04:48

1 概述

最近负责项目代码升级这一部分,在这里做一个小结。要实现程序的远程升级,需要用到两个程序,一个是Bootloader,另一个就是APP。单片机开机首先执行Bootloader,然后对APP进行引导。

2 流程图

在我们的项目中两个程序的流程图大致如下:
Created with Raphaël 2.1.0开始BootLoader需要更新?app循环更新代码?接收,写入更新代码yesnoyesno
说明:需要更新时,通过GPRS模块向单片机发送代码更新指令和数据,然后单片机依次从模块中取出发开的代码数据,写入到flash中。然后写入相关更新数据到指定flash,重启单片机,在Bootloader中读取相关地址数据,获取更新程序的地址等信息,然后对程序进行跳转。

3 功能实现

需要把单片机flash,分成4个部分,分别是Bootloader,APP1,APP2,参数区。其中参数区一般几十个字节就够用,用于保存是否更新标识等信息,当前demo参数区信息为:

#define FLASH_UPDATE_FLAG_ADDR      FLASH_CONFIGDATA_ADDR#define FLASH_APP1_VISION_ADDR      FLASH_UPDATE_FLAG_ADDR+HALFWORD#define FLASH_APP2_VISION_ADDR      FLASH_APP1_VISION_ADDR+VISION_SIZE#define FLASH_APP1_LENGTH_ADDR      FLASH_APP2_VISION_ADDR+VISION_SIZE#define FLASH_APP2_LENGTH_ADDR      FLASH_APP1_LENGTH_ADDR+HALFWORD#define FLASH_APP1_CRC_ADDR         FLASH_APP2_LENGTH_ADDR+HALFWORD#define FLASH_APP2_CRC_ADDR         FLASH_APP1_CRC_ADDR+HALFWORD#define FLASH_CURRENTAPP_FLAG_ADDR  FLASH_APP2_LENGTH_ADDR+HALFWORD

3.1 Bootloader主要代码

在Bootloader中主要是开机读取flash参数区用于更新,然后对程序进行引导,其跳转程序为:

void iap_load_app(u32 appxaddr){    if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)  //判断地址合法    {         __set_CONTROL(0);                      //特权模式        __ASM("CPSID  I");                     //关中断        jump2app=(iapfun)*(vu32*)(appxaddr+4); //程序开始地址为代码区第二字                  MSR_MSP(*(vu32*)appxaddr);             //初始化堆栈指针        jump2app();                            //跳转     }}   

3.2 APP主要代码

在APP,和平常不同的主要是两个方面,一个是代码存放的地址,如果是通过JLink升级,下载的地址需要更改
这里写图片描述
二是,程序开始时需要加上,这两句代码

    SCB->VTOR = FLASH_BASE | 0x04000;  //修改中断向量表    __ASM("CPSIE  I");                 //开中断

4 其他

这里有几个需要注意的细节
1.在用到RTOS时,在跳转时一般都要在跳转前开启特权模式以及关中端,然后在APP中一开始打开中断。
2.由于中断向量的关系,跳转程序的起始位置需要是512字节的倍数。
3.flash的读取和写入一般都是半字操作的。
4.大容量的stm32每个扇区为2k,中容量为1k,这个在写入更新代码时需要注意。

原创粉丝点击