1,boot部分
核心代码如下
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;
void iap_load_app(uint32_t appxaddr)
{
/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
// bin文件前4个字节储存主栈顶(ram大小)信息,stm32g0b0ret6 flash为144k(0x2400), 所以前4个字节应为20024000
if (((*(__IO uint32_t*)appxaddr) & 0x2FFE0000 ) == 0x20020000)
{
__disable_irq();
HAL_DeInit();
/* Jump to user application */
// 起始地址偏移4存储为ResetHandler,是程序最先开始执行的地方,之后进入main函数
JumpAddress = *(__IO uint32_t*) (appxaddr + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
// 初始化主程序堆栈指针,指向跳转后存储的栈顶
__set_MSP(*(__IO uint32_t*) appxaddr);
JumpToApplication();
}
}
主要功能就是跳转,其中app的bin文件前4字节为栈顶地址,向后偏移4字节为程序入口地址,以上完成跳转进app
2,app部分
在boot跳转时防止终端生效,一般都会关中断__disable_irq();并且关闭已经初始化的外设HAL_DeInit();
因为app还会再重新初始化这些设置,此时需要注意,app的flsh偏移地址需要与boot跳转地址一致,有几处需要修改,
第1处,为编译准备STM32G0B0RETX_FLASH.ld中代码
MEMORY
{
RAM (xrw) : ORIGIN = 0x20010000, LENGTH = 80K
FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 448K
}
这样在boot跳转时就可以找到bin文件的栈顶地址和ResetHandler的地址了,
第2处,修改启动后的运行向量表偏移量,system_stm32g0xx.c
#define USER_VECT_TAB_ADDRESS //这里源文件是注释的,这里需要手动放开,或者在底下修改FLASH_BASH
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
// 这里就是app存储偏移量
#define VECT_TAB_OFFSET 0x00010000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
3,以上修改完成后就能正常运行跳转和app程序了