最近在体验国产芯片MM32F5260,想着如何使用bootloadr来实现程序的跳转,为以后在Qspi中烧写程序做准备。
翻阅了好多资料,都没有找到这方面的文章,通过一天的试验,终于可以实现跳转了。现在分享如下:
【FLASH规划】
MM32F5260的内部FLASH为256K,从地址0x8000000开始。分配16K给bootloader来使用。然后剩余的240K给app使用。
在keil中需要修改几个地方
1、boot中的sct文件中,我定义代码的起始地址以及长度如下:
#define __ROM_BASE 0x08000000
#define __ROM_SIZE 0x00004000
2、在下载地址设置中设置如下:
在擦写设置为Erase Sectors。
【跳转代码】
#define FLASH_JUMP_ADDR (0x08004000)
typedef void (*pFunction)(void);
void JumpToApplication(uint32_t appAddress)
{
pFunction AppStart;
// 验证栈顶地址
uint32_t stackPointer = *(volatile uint32_t*)appAddress;
if((stackPointer < 0x30000000) || (stackPointer > 0x3001FFFF)) {
while(1);
}
// 关闭所有中断
__disable_irq();
// 设置向量表偏移
SCB->VTOR = appAddress;
// 设置主堆栈指针
//__set_MSP(stackPointer);
// 获取复位向量前的日志输出
printf("Before getting reset vector\n");
// 获取复位向量
AppStart = (pFunction)*(volatile uint32_t*)(appAddress + 4);
// 获取复位向量后的日志输出
printf("Reset vector obtained: %p\n", AppStart);
// 跳转前清理状态
SysTick->CTRL = 0;
// 执行跳转前的日志输出
printf("Before jumping to application\n");
// 执行跳转
AppStart();
}
代码中详细的功能在注释中已经注明。
main主函数如下:
int main(void)
{
PLATFORM_Init();
JumpToApplication(FLASH_JUMP_ADDR); // Jump to APP
//GPIO_LED_Toggle_Sample();
while (1)
{
}
}
【APP设置】
在APP中,首先也需要修改.sct的设置,将ROM的地始地址设置为0x8004000
#define __ROM_BASE 0x08004000
#define __ROM_SIZE 0x0003C000
在下载设置中也需要重新定义ROM的地始:
在main.c的起始指定程序开始的地址。同时还需要打开总中断,要不SysTick不工作。
int main(void)
{
SCB->VTOR = 0x08004000; // ??APP_START??
__enable_irq();
PLATFORM_Init();
PLATFORM_InitDelay();
GPIO_LED_Toggle_Sample();
while (1)
{
}
}
然后下载程序到开发板,就可以实现APP的跳转了。