gcc编译-hal库-stm32f4xx串口IAP升级
gcc编译hal库方式实现STM32F4系列芯片IAP升级
1、Bootloader程序:
调用iap_load_app函数即可,输入参数为app起始地址
void iap_load_app(uint32_t appxaddr)
{
uint32_t sram_addr = 0;
sram_addr = (*(__IO uint32_t *)appxaddr) & 0x2FFE0000;
printf("sram_addr : %08lx\n", sram_addr);
//APPLICATION_ADDRESS是在FLASH中存放APP的起始地址
//1、此判断是为了保证APP的栈地址是在SRAM中。其实结果并不一定是0x20000000。有些APP可能定义的全局变量较多,那么栈的起始地址会偏移。
//2、这里if()判断值0x20020000可以根据上面printf()的sram_addr的值修改
if (((*(__IO uint32_t *)appxaddr) & 0x2FFE0000) == 0x20020000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t *)(appxaddr + 4);
printf("jump addr : %08lx\n", JumpAddress);
Jump_To_Application = (pFunction)JumpAddress;
/* Initialize user application's Stack Pointer */
MSR_MSP(*(__IO uint32_t *)appxaddr);
printf("appxaddr : %08lx\n", appxaddr);
/*关闭或反初始化前面用到的外设和中断*/
HAL_DeInit();
/*跳转可能出现卡死,设置所有时钟到默认状态,使用HSI时钟*/
HAL_RCC_DeInit();
Jump_To_Application();
}
}
其中MSR_MSP()函数
void MSR_MSP(u32 addr)
{
__ASM volatile("MSR MSP, r0");
__ASM volatile("BX r14");
}
其中JumpAddress定义
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
uint32_t JumpAddress;
2、APP程序:
//定义基础地址
#define STM32_FLASH_BASE 0x08000000
在mian()函数一开始调用配置偏移量,0x10000根据需要自定义,与下面ld文件配置保持一致
int main(void)
{
/* USER CODE BEGIN 1 */
SCB->VTOR = STM32_FLASH_BASE | 0x10000;
修改.ld文件,例如STM32F407ZETx_FLASH.ld
flash修改为自己的application程序起始地址
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 124K
}
时间:2021.04.08
参考:https://www.cnblogs.com/armfly/p/13373014.html