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

我是FPGA+MCU的开发板
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];;
通过FPGA将APP的hex文件烧录到外置Flash的0x300000地址上

因为我们的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];}
}
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 vectorSCB->VTOR = APPADDRESS;f_jmp_app(APPADDRESS);
首先是看看hex是否写入了SRAM的指定地址,将hex和memory对比是否一致,
memory窗口0x18000000地址的开始数据

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