IAP的原理网络上有很多文章,我参考的是这一篇,写的比较好
这是最后一篇了,五精华无悬念:STM32的IAP方案 - stm32/stm8 - 电子工程世界-论坛 (eeworld.com.cn)
这里不再介绍原理了。本人看了原理,尝试了写了个简单的验证程序,结果跳转成功后中断不灵了,又查了很多网文,发现是uboot中是在中断中触发了跳转导致的异常,后来修改成直接在main函数中执行跳转,就成功了。这里记录一下关键点,并把工程源码也附上,供人参考。
UBOOT
#define APPLICATION_START_ADDR (uint32_t)(0x08001000)
typedef void (*pFunction)(void);
uint32_t JumpAddress = 0;
pFunction JumpToApplication;
s32 main(void)
{
DELAY_Init();
LED_Init(); //这里点灯的目的是方便观察运行在APP还是uboot上
LED2_ON();
DELAY_Ms(200);
LED2_OFF();
DELAY_Ms(200);
LED2_ON();
DELAY_Ms(200);
LED2_OFF();
DELAY_Ms(200);
LED2_ON();
DELAY_Ms(200);
LED2_OFF();
DELAY_Ms(200);
//IAP跳转,不能在中断程序中执行,否则切换到APP后中断异常
JumpAddress = *(volatile uint32_t *)(APPLICATION_START_ADDR + 4);
JumpToApplication = (pFunction) JumpAddress;
__set_MSP(*(volatile uint32_t *)APPLICATION_START_ADDR);
JumpToApplication();
//IAP跳转
while(1)
{
}
}
APP
#define APPLICATION_START_ADDR (uint32_t)(0x08001000)
s32 main(void)
{
memcpy((uint8_t *)SRAM_BASE, (uint8_t *)APPLICATION_START_ADDR, 48*4); //这里复制中断向量表
RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFG, ENABLE);
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
DELAY_Init();
LED_Init();
KEY_Init();
EXTI_Config();
while(1)
{
DELAY_Ms(200);
LED1_TOGGLE();
DELAY_Ms(200);
}
}
这里0xC0是48预留给中断向量的
0x10000-0x1000=0xF000
0x2000-0xC0=0x1F40