STM32 Cube IDE 下实现 IAP —— (1) 程序跳转

ST 推出自家的IDE:STM32 CubeIDE 有一段时间了,现在正好有新的项目了,尝试直接把它用起来了,不用再来回去切换 CubeMX 和其他 IDE 了。

目前的项目是要做一个 IAP 的框架,那就先从 Bootloader 到 APP 的程序跳转开始。手头正好有一块 NUCLEO-F072RB,就用它了。

首先新建一个工程:IAP_Bootloader

Bootloader 的一项任务就是要跳转到用户 APP 去执行。在 main.c 中新建一个函数 go2APP

#define FLASH_APP_ADDR 0x8008000
typedef void (*pFunction)(void);

void go2APP(void) {
  uint32_t JumpAddress;
  pFunction Jump_To_Application;

  printf("BOOTLOADER Start\n");

  //Check
  if (((*(__IO uint32_t*) FLASH_APP_ADDR) & 0x2FFE0000) == 0x20000000) {
    printf("APP Start...\n");
    HAL_Delay(100);
    // Jump to user application //
    JumpAddress = *(__IO uint32_t*) (FLASH_APP_ADDR + 4);
    Jump_To_Application = (pFunction) JumpAddress;
    // Initialize user application's Stack Pointer //
    __set_MSP(*(__IO uint32_t*) FLASH_APP_ADDR);
    Jump_To_Application();
  } else {
    printf("No APP found!!!\n");
  }
}

先简单预留 32KB 给 Bootloader,所以 FLASH_APP_ADDR 就是从 0x8008000 开始。如何从串口 printf,可以参考这里 (STM32 Cube IDE 下实现串口 printf)

可以看到现在打出的 log 是:No APP found。简单说明一下判断是否有APP存在的机制,就是判断APP开头是否是合理的堆栈地址,而RAM地址是从 0x20000000 开始的。

接下里再来建立一个 IAP_APP 的工程。在 main.c 中,只是简单添加一句 printf(“APP Run\n”)。主要需要修改的生成的可以执行文件的起始地址,需要修改 STM32F072RBTX_FLASH.ld

找到 FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K 一句,修改为 FLASH (rx) : ORIGIN = 0x8008000, LENGTH = 96K。再来编译运行一下

如果使用了中断(通常都会用),还需要修改中断向量表的偏移量。

对于 STM32F1 系列,在文件 system_stm32f1xx.c 中搜索 VECT_TAB_OFFSET,原本的值通常为:0,在本例中需要改成 0x8000 即可。

对于 STM32F0 系列,由于没有中断向量偏移寄存器,需要手动复制中断向量表。在 main 函数开始处加入:

memcpy((void) 0x20000000, (void) 0x8000, 0x100);
SYSCFG->CFGR1 |= 0x03;

将中断向量复制到内存,并映射内存地址到 0x00000000 。

由于占用了系统内存的前256个字节,还需要再修改一下 STM32F072RBTX_FLASH.ld 排除这部分内存,以免被覆盖。找到 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K,修改为 RAM (xrw) : ORIGIN = 0x20000100, LENGTH = 16128 即可。

看到 APP Run 的 log 打出来,这样一个简单的从 bootloader 到 APP 的跳转就算完成了 ^o^


Add Your Comment

* Indicates Required Field

Your email address will not be published.

*