stm32上电到main()的启动流程

image

⚡ 一、硬件阶段(由 CPU 硬件自动完成)

当 STM32 上电或复位 时,Cortex-M 内核自动执行以下步骤:
注意:STM32上电复位以后,代码区都是从0x00000000开始的,三种启动模式将各自存储空间的地址映射到0x00000000中。

启动方式 启动地址映射到 0x00000000 启动内容 典型用途
主Flash启动(Main Flash boot) 主Flash(0x0800_0000) 用户应用程序 正常运行
系统存储器启动(System Memory boot) 系统存储器(0x1FFF_0000 或类似) 内置 Bootloader 串口 / USB / DFU 下载
SRAM启动(RAM boot) SRAM(0x2000_0000) 调试用 调试或特殊引导
步骤 动作 说明
取地址 0x00000000 的值 → 写入 MSP(主栈指针) 栈顶指针初始化
取地址 0x00000004 的值 → 写入 PC(程序计数器) 这就是 Reset_Handler 的入口地址
CPU 从 Reset_Handler 开始执行 程序正式启动

👉 这两步对应中断向量表的前两项:

0x00000000  __initial_sp   ; 初始栈顶
0x00000004  Reset_Handler  ; 复位入口

🧠 二、软件阶段(由启动文件与运行时库完成)

Reset_Handler 开始,一切都是软件控制。
以 STM32 官方启动文件为例,主要有以下过程:

阶段 执行函数 主要工作
Reset_Handler 初始化 SRAM、调用 SystemInit、再跳转到 __main
SystemInit() 配置时钟(HSE/HSI/PLL)、Flash、总线分频等硬件系统设置
__main(编译器库函数) 初始化 C 运行环境(复制 .data、清零 .bss、准备堆栈)
main() 进入用户编写的主函数

🔍 更细的展开(典型 ARMCC / Keil 流程)

上电或复位
    ↓
硬件加载 MSP、PC
    ↓
执行 Reset_Handler
    ↓
    ├─ 清空 SRAM (部分芯片)
    ├─ 调用 SystemInit()        ← 时钟初始化
    └─ 跳转到 __main
         ↓
         ├─ 拷贝 .data 段(Flash → RAM)
         ├─ 清零 .bss 段
         ├─ 初始化 C/C++ 运行环境
         └─ 调用 main()
              ↓
           用户程序开始运行

🧩 三、内存空间的状态变化

内存区域 内容 来源
Flash(程序存储器) 代码、常量、初始化数据 编译后固化
SRAM(数据存储器) 栈区、堆区、全局变量、静态变量 由 Reset_Handler / __main 初始化
寄存器 MSP、PC、PSP、CONTROL、PRIMASK... 由 CPU 自动或系统代码设置

🧱 四、Reset_Handler 中的重要三步(再次总结)

  1. 初始化 SRAM(可选)
    清零 RAM 或建立默认值;
  2. 调用 SystemInit()
    配置系统时钟、外设基础环境;
  3. 跳转到 __main
    由编译器运行时库初始化 C 语言环境,最后进入 main()

💡 五、通俗比喻

阶段 类比
上电/复位 打开电脑电源
硬件取向量表 BIOS 启动,知道去哪执行
Reset_Handler BIOS 初始化硬件
SystemInit 设置 CPU 频率、时钟源
__main 操作系统加载应用环境
main 程序员写的应用程序开始运行

✅ 最简总结(记住这 6 步即可)

上电复位 →
取向量表 →
MSP ← __initial_sp
PC  ← Reset_Handler
→ SystemInit()
→ __main()
→ main()

posted @ 2025-11-03 14:25  seekwhale13  阅读(36)  评论(0)    收藏  举报