STM32 Bootloader与启动分析

一、STM32 程序下载与Bootloader
 三种启动模式如下表:

(截图与stm32中文参考资料)

1、从主闪存存储器启动,即从STM32内置的Flash启动,BOOT0=0,BOOT1=X, 一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,复位(软件复位、手动复位、硬件自动复位)后也直接从这启动程序。不需要使用到系统存储区的Bootloader程序。

2、从系统存储器启动,即STM32的ISP了。B00T0=1,B00T1=0,由于串口不能直接把程序下载到内置的flash里面,所以需要使用到ST公司内嵌于系统存储区(flash的某一部分的地址被编为0x1FFF_F000-0x1FFF_F7FF,这就是所谓的系统存储器\区)的Bootloader来引导把程序下载到flash里面。程序下载完成后还需要配置BOOT[1:0]引脚为BOOT0=0,BOOT1=X(即从主闪存存储器启动),复位后启动程序(手动复位或者使用硬件自动复位电路)。下图是关于STM32F10xxx的Bootloader的一些信息

截图来自文档AN26062

截图来自文档AN26062

截图来自正点原子开发板

3、从内置SRAM启动。内置SRAM,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。

二、STM32启动分析

预备知识:

DCD指令:用于分配一片连续的字存储单元(32bit),并将表达式的值初始化给该字存储单元,类似于C中定义数组并初始化。比如: DCD 0 的意思是:分配一个字存储单元,并将该单元初始化为0。

分析:

在STM32的启动文件中可以看到有如下代码:

EXPORT __Vectors

__Vectors

DCD __initial_sp ; Top of Stack

DCD Reset_Handler

DCD NMIException

DCD HardFaultException

DCD MemManageException

DCD BusFaultException

DCD UsageFaultException

DCD 0 ; Reserved

DCD 0 ; Reserved

DCD 0 ; Reserved

DCD 0 ; Reserved

DCD SVCHandler

DCD DebugMonitor

DCD 0 ; Reserved

DCD OSPendSV

……

这一段是分配STM32的中断向量表。从DCD后面表达式的名称可以看出第一个字存储单元分配给了栈顶,其值为__initial_sp。第二个字分配给了复位地址,其值为Reset_Handler,后面接着分配给其他异常或中断。

这里的Reset_Handler,NMIException等,其实是一个地址值,也就是中断处理函数的入口地址。在函数实现时,由编译器分配一个地址值。

那么这里就有两个问题。

第一个是为什么是这样的分配顺序?

第二个是DCD后面表达式的值,即各个中断函数的地址值如Reset_Handler,NMIException是如何分配的?

第一个问题的答案好找,我们参考《STM32参考手册》:

可以看到,启动文件中的向量表的分配的顺序是按照固定的规则来的。

第二个问题。随意打开一份编译过的工程,工程配置如下:

我们可以看到.map文件有这样一段:

同时使用J-Link打开.hex文件可以看到

从hex档,我们可以看到Flash的起始区域0x8000000的内容为

0x20000660

0x0800027D

0x08000281

0x08000283

……

刚好可以和map文件对应,也刚好可以和启动文件的向量表对应。

按照Cortex-M3权威指南,在复位后,有如下动作:

我这里是选择从flash启动,根据寄存器映射,Address从0x00000000映射到0x08000000。所以hex档的内容刚好满足复位序列的设定。

由此从启动文件到.map文件再到.hex文档,再到CM3复位启动的脉络就理清了。

作者:qq_30479727
来源:CSDN
原文:https://blog.csdn.net/qq_30479727/article/details/63352897
版权声明:本文为博主原创文章,转载请附上博文链接!

没有更多推荐了,返回首页