STM32F0/G0 Bootloader(IAP)原理及实现

1.BOOT程序放在flash开始处

   如下图,实现Bootloader的程序(BOOT)放到Flash开始地址(物理)处0x8000000.长度根据boot程序的大小限制一下;下图中设置了前8k为boot程序空间,这个设置要与用户程序的开始地址相匹配;

2.主要功能程序
 
  从UART读取数据后写入flash这里不再说明,可使用ST库函数轻松实现,以下为如何实现向用户程序的跳转:


  #define MAIN_USER_FLASH_BEGIN 0x8002000 //用户程序存储地址

  typedef void (*RESET_FUNCTION )(void); //复位函数模型
 
  //从BOOT程序跳转到用户程序
  void ExecApp(void)
  {
   uint32_t jump_addr=*((__IO uint32_t *)(MAIN_USER_FLASH_BEGIN+4));
    RESET_FUNCTION Reset=(RESET_FUNCTION)jump_addr;

   // ....

   __set_MSP(*(__IO uint32_t*)MAIN_USER_FLASH_BEGIN);
   Reset();
  }


 

3.用户程序
  如下图,用户程序的应定位到boot程序指定的用户程序开始地址处(示例中为0x8002000),另外在ram的前192个字节(48个32位地址)用于存放中断向量;


用户程序首先需要做的就是将中断向量从flash复制到ram,并将中断映射到ram,实现代码如下:
 

//用户程序存放地址(也是存放中断向量的flash地址)
#define APPLICATION_ADDRESS ((uint32_t)0x08002000)

//RAM中的中断向量
__IO uint32_t VectorTable[48] __attribute__((at(0x20000000)));

int main(void)
{
 uint32_t i;

 GPIO_InitTypeDef GPIO_InitStructure;

 //从flash中复制中断向量到ram
 for(i = 0; i < 48; i++)
 {
  VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
 }

 //中断向量映射到RAM(开始地址处)
 SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
 
  //__HAL_SYSCFG_REMAPMEMORY_SRAM();//如果是HAL库
 //...

}

  
中断向量映射的原理其实就是存储器地址映射,以STM32G0的存储器地址为例,如下图。中断向量的地址总是在0x0000 0000,是不变的,好在这个地址是个可以映射的地址、没有具体分配给某一类存储器,如果这个地址映射到flash那这个地址就等同于0x0800 0000,如果映射到ram那这个地址就等同于0x2000 0000,也就是在中断产生时CPU就会从ram的中断对应处取指令。

示例代码请到 CAS-BOOT项目 下载!
 

本站广告:
  ENC28J60+uIP 基于TCP的MODBUS IO示例
  ENC28J60+uIP DHCP动态获取IP及UDP广播服务端示例
  ENC28J60+uIP HTTP GET方式将温度数据上传到web服务器
  C720H5上实现MODBUS远程IO
  FM1702读写S50(也叫M1)卡相关资料
  SYN480R+MCU实现遥控开关示例
  STM8S003学习型红外软解码遥控开关
  STM8S003学习型射频软解码遥控开关
  STM32通过TF卡(sd/mmc)升级程序

 

芯艺工作室    蒙ICP备06005492号

Copyright© 2004-2020 ChipArt Studio All Rights Reserved