Stm32启动

发布于:2025-08-12 ⋅ 阅读:(20) ⋅ 点赞:(0)

STM32 的启动过程有一套固定且标准化的流程(俗称 “启动八股文”),从硬件复位到进入main函数,每一步都有明确的逻辑。理解这套流程是开发 STM32 的基础,下面按顺序拆解核心步骤:

一、硬件复位与启动方式选择

  1. 复位触发
    当 STM32 上电、外部复位引脚(NRST)被拉低,或软件触发复位时,CPU 进入复位状态,所有寄存器恢复默认值。

  2. 启动方式由 BOOT 引脚决定
    复位后,STM32 通过BOOT0 和 BOOT1 引脚的电平组合,决定从哪个存储区域启动(读取中断向量表),常见组合:

    • BOOT0=0,BOOT1=0:从主 Flash启动(最常用,程序固化在 Flash 中)。
    • BOOT0=1,BOOT1=0:从系统存储器启动(用于 ISP 下载,如通过串口烧录程序)。
    • BOOT0=0,BOOT1=1:从SRAM启动(用于调试,程序不固化,掉电丢失)。

二、读取中断向量表,初始化堆栈

  1. 中断向量表的位置
    启动介质(Flash/SRAM/ 系统存储器)的起始地址存放中断向量表(一个指针数组,每个元素是中断服务程序的入口地址)。

    • 向量表第一个元素:栈顶地址(MSP 初始值)
    • 向量表第二个元素:复位中断服务程序(Reset_Handler)的入口地址
  2. 初始化主栈指针(MSP)
    CPU 首先从向量表第一个元素中读取栈顶地址,赋值给主栈指针(MSP),为后续函数调用、局部变量分配栈空间做准备(栈大小在启动文件中配置,如Stack_Size EQU 0x400)。

三、跳转至复位中断服务程序(Reset_Handler)

CPU 从向量表第二个元素中读取复位中断服务程序的地址,跳转到该程序执行(这是启动流程的核心入口,由启动文件的汇编代码实现)。

四、系统时钟初始化(SystemInit)

复位后,STM32 默认使用内部高速时钟(HSI,8MHz),但实际开发中需切换到更高频率(如 72MHz、168MHz 等)。
复位中断服务程序中会调用SystemInit函数(在system_stm32xxxx.c中实现),完成:

  • 切换系统时钟源(如外部高速时钟 HSE、PLL 锁相环)。
  • 配置 AHB、APB1、APB2 总线分频,确定外设时钟频率。
  • 初始化时钟树相关寄存器(RCC 寄存器)。

五、初始化数据段(Data Segment)和 BSS 段

程序的全局变量、静态变量需要在main函数执行前初始化,这一步由启动文件的汇编代码完成:

  1. 数据段(.data)初始化

    • 已初始化的全局 / 静态变量(如int a = 10;)在 Flash 中存储初始值,启动时需复制到 SRAM 的.data 段。
    • 操作:从 Flash 的_sidata(数据初始值地址)复制到 SRAM 的_sdata(数据段起始地址),直到_edata(数据段结束地址)。
  2. BSS 段(.bss)初始化

    • 未初始化或初始化为 0 的全局 / 静态变量(如int b;static int c = 0;)存放在 BSS 段,启动时需清零。
    • 操作:将 SRAM 中_sbss(BSS 段起始地址)到_ebss(BSS 段结束地址)的区域全部赋 0。

六、调用用户主函数(main)

完成上述初始化后,启动文件会通过汇编指令(如bl main)跳转到用户编写的main函数,程序进入应用逻辑执行阶段。

核心依赖:启动文件(startup_stm32xxxx.s)

整个启动流程的硬件初始化、向量表定义、段复制等操作,都由启动汇编文件实现(如startup_stm32f103xe.s)。该文件包含:

  • 中断向量表的定义(对应不同中断的服务程序入口)。
  • 复位中断服务程序(Reset_Handler)的实现。
  • 栈(Stack)和堆(Heap)的大小配置(可根据需求修改,堆用于malloc动态分配)。

总结:STM32 启动 “八股文” 流程

plaintext

硬件复位 → BOOT引脚选启动介质 → 读向量表初始化MSP → 跳转到Reset_Handler → 
SystemInit配置时钟 → 复制.data段、清零.bss段 → 跳转至main函数

这套流程是 STM32 的 “必经之路”,理解后能更清晰地排查启动故障(如时钟配置错误、栈溢出、向量表地址错误等)。


网站公告

今日签到

点亮在社区的每一天
去签到