终于实现了BootLoader到APP的跳转,下面说下如何操作。
首先是跳转函数:
- void go_to_app(uint32_t AppAddress)
- {
- uint32_t JumpAddress;
- if(((*(__IO uint32_t *)AppAddress)&0x2FFE0000)==0x20000000)
- {
- //__disable_irq();
- __ASM(“CPSID I”);
- JumpAddress = *(__IO uint32_t *)(AppAddress+4); // Jump to user application
- Jump_To_Application = (pFunction)JumpAddress; // Initialize user application’s Stack Pointer
- __set_MSP(*(__IO uint32_t*)AppAddress);
- Jump_To_Application();
- }
- else
- {
- printf(“No Jump\n”);
- }
- }
注意,stm32是小端存储,取 AppAddress中的数据时一定要检查下向量地址是否正确。
在APP程序中要进行以下设置:
1. 将程序定位在0X08010000开始的位置。
点魔术棒,打开目标选项设置。
选Target选项卡,IROM1改成从0X08010000开始,尺寸0X00010000;
Debug选项卡,Load Application at Startup打上勾,Run to main()打上勾;
Utilitiles选项卡,点settings按纽,弹出Flash download卡,Erase sectors打上勾,点你的编程算法,将底下的的起始地址改成0X08010000,尺寸0X00010000。
3. 为了从IAP程序跳来运行APP的时候正常开始,初始化时要恢复RCC为复位状态,恢复NVIC为复位状态。
在你的RCC初始化部分,第一句加上:
RCC_DeInit();
在你的NVIC初始化部分,第一句加上:
NVIC_DeInit ();
4. 重定位中断表到0X08010000位置。
在上面NVIC_DeInit ();后面加上:
NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x00010000);
如果原来有其它的定位语句,将它删掉。
由于我的程序不需要从 App跳到bootloader,所以在 bootloader没有进行上述设置。并且在初始化程序中,我只设置了向量偏移,即:
NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x00010000);
因为我发现,设置 RCC_DeInit()后,系统时钟被改变了。而NVIC_DeInit()在新的库函数中被取消了,也没有用到。
进行以上设置后,分别用keil烧写两个程序,MCU可以正常工作了。
我也是机械出身的单片机开发。just like
共勉