如果已经有一些汇编基础,理解 STM32 启动流程会轻松不少。汇编比 C语言 更接近硬件底层,能让我们更清楚地看到芯片上电后到底执行了什么。
STM32 三种启动模式
程序下载完成并重启芯片后,SYSCLK 的第 4 个上升沿会锁存 BOOT 引脚的电平,这个动作就决定了启动模式。STM32 上电或复位后,代码区始终从 0x00000000 开始,本质上就是把对应存储空间的地址映射到 0x00000000。三种启动模式如下:
- 从主闪存存储器启动:将主 Flash 地址
0x08000000 映射到 0x00000000,代码启动后相当于从 0x08000000 开始执行。主闪存存储器是 STM32 内置的 Flash,属于正常工作模式。一般通过 JTAG 或 SWD 下载程序时,代码就写入这里,重启后也从这里启动。
- 从系统存储器启动:控制
BOOT0、BOOT1 引脚后复位,STM32 会从系统存储器地址 0x1FFF F000 开始执行代码。系统存储器是芯片内部出厂时预置的一块区域,里面有一段 Bootloader,也就是常说的 ISP 程序。这块区域出厂后无法修改或擦除,属于 ROM 区,启动功能由厂家预设。
- 从内置 SRAM 启动:将 SRAM 地址
0x20000000 映射到 0x00000000,代码启动后相当于从 0x20000000 开始。SRAM 是易失性存储器,本身不能固化程序,因此这个模式多用于调试。比如只改一小处代码就要擦除整个 Flash 比较耗时,可以先从 SRAM 启动做快速调试,等程序调试完成后再固化到 Flash。
用户通过设置 BOOT1 和 BOOT0 引脚的状态,即可选择复位后的启动模式。STM32 三种启动模式对应的存储介质都集成在芯片内部,如下图:

串口下载程序原理
从系统存储器启动时,执行的是厂家出厂预置的 Bootloader。这种启动方式平时用得不多,但它是串口下载程序的基础。系统存储器是一块 ROM,ST 出厂时在其中写入了 ISP 程序,用户无法再修改。关于 ISP 的更多细节,可参考 STM32单片机中Hex、Bin文件的区别与应用。
选用这种启动模式,通常就是为了通过串口下载程序,因为厂家提供的 Bootloader 中包含了串口下载固件,可以把程序写入系统 Flash。下载过程需要以下几步:
- 将
BOOT0 置为 1,BOOT1 置为 0,然后按下复位键,让芯片从系统存储器启动 Bootloader;
- 在 Bootloader 的帮助下,通过串口把程序下载到 Flash;
- 下载完成后,把
BOOT0 重新接回 GND,并手动复位,这样 STM32 才能从 Flash 启动。
从汇编代码分析 STM32 启动过程
STM32 的启动文件与编译器强相关,不同编译器对应的启动文件并不相同。关于启动文件的细节,可参考 详解STM32启动文件。不过这些启动文件虽然写法有差异,但都属于汇编程序,原理类似。下面以 MDK-ARM 的启动文件为例,看几个重点内容。文件开头有一段汇编代码,用来分配堆栈大小。

这里重点看堆栈数值:Stack_Size 和 Heap_Size。后续还会用 AREA 定义一段堆栈数据段。这些数值也可以通过 STM32CubeMX 来配置:

在 IAR 中,则是通过工程的链接器配置来设置堆栈大小:

继续看下面的汇编代码。芯片上电后,会先跳到 Reset_Handler 这个入口位置。

知道代码从 Reset_Handler 开始执行后,再看 Reset_Handler 的具体汇编实现。启动时先执行了 SystemInit 这个函数。

SystemInit 负责初始化系统时钟,执行完成后,程序跳转到 main 函数开始运行。
|