从bootloader跳到APP需要几步?
从bootloader跳到APP需要几步?
对于bootloader跳转到APP具体流程,我们用下面一个例子去讲解。首先将 bootloader 程序和 app 程序的大小都是 2K ,bootloader 从 0x08000000 到 0x080007FF , app 程序从 0x08000800 到 0x08000FFF 。
接下来看 bootloader 代码的实现:
#include "stm32f10x.h"
uint32_t JumpAddress = 0;
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
#define FLASH_BASE_ADDRESS ((uint32_t)(0x08000000))
#define Application_Address ((uint32_t)(0x08000800))
int main(void)
{
JumpAddress = *(__IO uint32_t*)(Application_Address+4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) FLASH_BASE_ADDRESS);
Jump_To_Application();
}
对于 bootloader 程序,我们首先设置了 pc 指针为0x08000804,然后设置了栈顶指针,最后执行 pc 指针指向的地址。
我们可以利用map文件查看使用 rom 的大小:
接着我们来看 app 程序:
#include "stm32f10x.h"
uint16_t i = 0;
int main(void)
{
SCB->VTOR = FLASH_BASE | 0x800;
i++;
while(1);
}
在 app 程序中我们首先得设置中断向量表偏移地址,然后再执行后面得程序,同样我们也可以使用 map 文件查看花费 rom 的大小:
我们可以看到 rom 花费了0.83kb ,原因是在执行应用代码前又执行了时钟配置,因此我们可以在启动文件的复位中断函数注释掉:
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
;IMPORT SystemInit
;LDR R0, =SystemInit
;BLX R0
LDR R0, =__main
BX R0
ENDP
接着我们继续编译,发现花费的 rom 比之前降低了:
需要注意的是在编译前,我们得对编译器做些配置,将 bootloader 的起始地址配置为 0x08000000,将 app 的起始地址配置为0x08000800。
我们对 bootloader 程序进行调试,我们可以看到 SP 指针已经设置为 0x08000000 指向的位置0x20000408:
同时,执行完 bootloader 程序后,我们开始执行app程序,在app程序里我们得先设置中断向量表偏移,接着单步执行,可以看到可以正常执行。