Bootloader
为啥要做一个bootloader,因为最近客户调试MCU中,中断向量表和代码不设置一个区域内,在0x0的地址放置中断向量表,并在0x18000000的地址放置代码,发现会有一点问题,想测试一下在0x18000000的地址是否有问题,所以做了个Bootloader
1.解释原理
Bootloader其实是一个程序引导的过程,将APP的程序从板子的某个固定存储器Flash中“搬运到”SRAM/RAM中,将MSP和PC指针指向我们的APP的程序,就可以跑起来了

2.Bootloader到APP的步骤
我是FPGA+MCU的开发板
1.ARM准备APP
1.我们首先准备一个APP的ARM工程,然后编译后的hex文件通过FPGA去烧录到Flash中,这里使用的时led亮灭的APP,对照自己的芯片修改工程
void delay(int n)
{
int i, j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= 1000; j++) {
__NOP();
}
}
return;
}
int main(void)
{
HME_GPIO_InitTypeDef Init;
HME_GPIO_DeInit(PORTA);
Init.Mode = PIN_MODE_OUTPUT;
Init.Pins = GPIO_PIN1;
HME_GPIO_Init(PORTA, &Init);
while (1) {
HME_GPIO_Set(PORTA, GPIO_PIN1);
delay(5000);
HME_GPIO_Clear(PORTA, GPIO_PIN1);
delay(5000);
}
return 0;
}
同时把APP的程序存储的起始地址为0x18000000

2.FPGA的工程配置一个led引脚
assign ledo=gpio_porta_dr[1]&gpio_porta_ddr[1];;
2.FPGA烧录hex文件
通过FPGA将APP的hex文件烧录到外置Flash的0x300000地址上

3.SPI读hex文件并写入SRAM
因为我们的MCU是有SRAM的,将Flash上地址为0x300000的代码写到指定位置0x18000000的SRAM上
一次页写是256Byte的数据,hex文件没有那么小,一次肯定不够,同时对地址赋值
for(k = 0 ; k < (APP_SIZE>>8) + 1 ; k++)
{
spiFlashPageRead(inData,0x300000+256*k, DEMO_SPI_PAGE_SIZE);
for(j = 0;j < DEMO_SPI_PAGE_SIZE;j++)
{
*(unsigned int *)(0x10000000+j+256*k) = inData[j];
}
}
4.Bootloader跳转
f_jmp_app这个函数是汇编语言的,我其实也不太懂,就是给SP,PC两个指针跳转就完事了,具体情况看实现Cortex-M3内核芯片(如STM32,LPC1768)的boot升级跳转到APP操作
#define APP_SIZE 0x3F0
#define APPADDRESS 0x18000000
__asm void f_jmp_app(uint32_t address)
{
LDR SP, [R0]
LDR PC, [R0, #4]
}
__disable_irq();
//set intr vector
SCB->VTOR = APPADDRESS;
f_jmp_app(APPADDRESS);
5.Debug调试
首先是看看hex是否写入了SRAM的指定地址,将hex和memory对比是否一致,
memory窗口0x18000000地址的开始数据

memory窗口0x180003EC地址的最后数据
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZO5WLSQq-1668504280538)(Bootloader.assets/1668499638952.png)]](https://img-blog.csdnimg.cn/99f15854d4e9440faa29f60a03c014d3.png)
对应hex文件的数据
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Oe8FmOz-1668504280539)(Bootloader.assets/1668499558806.png)]](https://img-blog.csdnimg.cn/5ecd899abd2a4c84880d3e7c3a7195a3.png)
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MXsPUyO8-1668504280539)(Bootloader.assets/1668499597134.png)]](https://img-blog.csdnimg.cn/f56df25dd34e4f65879acc1824d477a2.png)
发现是一致的,说明APP的代码是已经搬过来了
然后是看SP和PC指针的跳转
SP指针成功跳转到了0x18004600的地址
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kerpeKfZ-1668504280539)(Bootloader.assets/1668500169327.png)]](https://img-blog.csdnimg.cn/fbd1c4ccb66342218823bfe57bbd26b9.png)
对照APP的map文件,SP栈顶指针指向的是0x18004600的地址
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WKLwOned-1668504280539)(Bootloader.assets/1668500446548.png)]](https://img-blog.csdnimg.cn/d3314f05274b4890aa0ef396d17373f6.png)
PC指针跳转到了0x180000B8的值
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rq6lOgPU-1668504280540)(Bootloader.assets/1668502508243.png)]](https://img-blog.csdnimg.cn/17c4c5255af54ab696d12e149c5fe986.png)
对照APP的map文件,PC栈顶指针指向的是0x180000B9的地址
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cHZRteXI-1668504280540)(Bootloader.assets/1668502596255.png)]](https://img-blog.csdnimg.cn/bd2e0f469f244088967777eaf9af35a2.png)
因为ARM 内核有历史遗留问题,反正指针就是-1,是没有问题的
3.总结
做了本次调试,熟悉了Bootloader的整体流程和MCU的启动过程,其实就是把程序换了个地址开始启动,一般来说MCU的启动就是从0x0地址开始,SP和PC指针指向的就是默认的,现在多加了一个Bootloader的过程,再把程序放在了后面的地址了,SP和PC指针就得跳转到后面程序开始的地址了,简简单单的。但我还是在领导的帮助下,完成了调试。
我只是提供思路,说的不一定对。
4.参考资料
推荐看B站
从bootloader跳到APP需要几步?


















