赞
踩
最近笔者闲来无事打算设计自己的一个Bootloader程序,然后开了这个系列,记录在学习过程各个要点
以上是来自百度定义,很明显好像和我们想象不太一样,因为大多数时候Bootloader都是来下载程序,那为什么和引导程序有关系呢?
一下是 AT32 的 AN0001 中对Bootloader(也称IAP)的过程描述:
是不是看的一脸懵逼?没事,我刚开始看到时候也懵逼。该过程也可以被描述为一下阶段:
- 1.上电进入Bootloader程序
- 2.检测是否有刷新APP(你的应用程序)的标志
- 3.有则通过通讯接口(USB,串口,CAN等)下载,没有则跳转应用APP
- 4.在应用APP中检测是否有升级相关的信息出现,如果出现,则复位系统
接着就来讲讲今天的重点
该图取自 AT32 寄存器手册中,关于系统上电过程,实际上不只是AT32,STM32,GD32等,这些Coretx M3与M4内核的芯片的上电过程都差不多,复位之后的步骤:
通过对 AT32f421 进行Debug调试可以查看到,在地址0x0000_0000处存放的是0x2000_0E80(高地址在高位)传递给了R13(MSP,主栈指针),在地址0x0000_0004存放的0x0800_0169传递给了R15(PC,程序计数器)?
但是大家可能会好奇,为什么明明是0x0800_0169,但是R15里面是0x0800_0168呢?
但是在启动流程图中,第二条已经说明:
这个值是复位向量, LSB必须是1。然后从这个值所对应的地址处取指。
所以在这个地址应该是0x0800_0168,只不过LSB被强制置1,变成了0x0800_0169。
但是0x0800_0168到底是什么呢?
根据查看,Reset_Handler(复位中断入口)的的函数的入口地址就是0x0800_0168,也就是说0x0000_0004存放的是Reset_Handler的地址,复位后,程序先跳转进入Reset_Handler,在Reset_Handler中对时钟进行初始化,然后跳转进入我们main函数
那么这些本质原因是什么呢?
这些本质上就是著名的中断向量表
以上是 Cortex M3 权威指南 中的说明中断向量表,就是所有的中断函数的入口地址都被记录在一个表中,从地址0x0000_0004处开始,每表项占用4给字节也就是32bit,为32bit的原因很简单,因为Cortex M3的位宽是32bit,地址线也是32bit,要在32bit的范围内寻址。 当中断被响应的时候,内核就会在中断向量表中找到对应的中断,再将对应的中断地址传递给PC程序计数器,使代码跳转进入该中断函数。
既然要响应中断,那就必然会涉及到压栈,在 Cortex M3 权威指南 已经说明
响应异常的第一个行动,就是自动保存现场的必要部分:依次把xPSR, PC, LR, R12以及R3‐R0由硬件自动压入适当的堆栈中
所以当中断响应的时候,会硬件压栈,而复位也是一个中断,所以在跳转到复位函数前要初始化**MSP(主栈指针)**的原因,让主栈指针到对应的内存地址为复位中断提供正确的栈地址和空间。(Cortex M4内核也是差不多的)
本次文章重点讲述了关于Cortex M3与Cortex M4的上电启动过程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。