单片机在main()函数之前是怎么运行
这次我来记录下单片机在 main() 函数之前是怎么运行的。
这是别人帖子上的图。
2. STM32 启动模式
STM32 上电或复位后,代码区始终从 0x00000000 开始,其实就是将存储空间的地址映射到 0x00000000 中。三种启动模式如下:
-
从主闪存存储器启动:将主 Flash 地址 0x08000000 映射到 0x00000000,这样代码启动之后就相当于从 0x08000000 开始。主闪存存储器是 STM32 内置的 Flash,作为芯片内置的 Flash,是正常的工作模式。一般我们使用 JTAG 或者 SWD 模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。一般我们都用这种模式。
-
从系统存储器启动:首先通过控制 BOOT0、BOOT1 引脚,复位后,STM32 与上述两种方式类似,从系统存储器地址 0x1FFF F000 开始执行代码。系统存储器是芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段 Bootloader,就是通常说的 ISP 程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个 ROM 区。启动的程序功能由厂家设置。系统存储器存储的其实就是 STM32 自带的 bootloader 代码。
-
从内置 SRAM 启动:将 SRAM 地址 0x20000000 映射到 0x00000000,这样代码启动之后就相当于从 0x20000000 开始。内置 SRAM,也就是 STM32 的内存,既然是 SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个 Flash,比较费时,可以考虑从这个模式启动代码,用于快速的程序调试,等程序调试完成后,再将程序下载到 SRAM 中。
用户可以通过设置 BOOT1 和 BOOT0 引脚的状态,来选择在复位后的启动模式。STM32 三种启动模式对应的存储介质均是芯片内置的,如下图:

1. 启动流程
-
单片机上电后,程序首先跳转到地址 0 处,此时主堆栈指针 MSP 的初值也为 0。然后单片机产生了复位信号,主堆栈指针加 1,由于单片机内核为 32 位,所以地址增加一位,实际上是增加了 32 位,也就是增加了 4 个字节。此时 MSP 指针就指向了复位向量。而 Cortex-M 内核处理器的向量表可以重新定位,所以此时程序就会跳转到复位向量重新映射的地址处。
-
通过复位向量的重映射后,MSP 指针就会跳转到复位向量处。这里我理解复位向量的地方就是
Reset_Handler。如果是 STM32F1 系列单片机中,复位向量的函数通常在启动文件startup_stm32f10x_xx.s中实现。

- 我们可以看到首先进入
Reset_Handler。复位函数首先获取到了main()函数和系统初始化函数SystemInit()的地址,然后跳转到系统初始化函数SystemInit()中,接着就会跳转到main函数中。
SystemInit 里面就是各种时钟配置了,之后就会进入 main() 函数了。
参考阅读:
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)