STM32 单片机启动过程全解析:从上电到主函数的旅程

news2025/6/4 21:05:36

一、为什么要理解启动过程?

STM32 的启动过程就像一台精密仪器的开机自检,它确保所有系统部件按既定方式初始化,才能顺利运行我们的应用代码。对初学者而言,理解启动过程能帮助解决常见“程序跑飞”“不进 main”“下载后无反应”等问题;而对资深开发者,则有助于进行裸机编程、启动优化、Bootloader 设计等工作。


二、STM32 启动流程概览

STM32 的启动过程大致可以划分为以下几个阶段:

 

上电 / 复位     ↓启动模式选择(BOOT 引脚)     ↓向量表定位(读取复位向量)     ↓跳转至启动代码(如 startup_stm32f10x.s)     ↓C/C++ 运行时初始化(.data/.bss/init)     ↓调用 main 函数

图片


 


三、详细流程剖析

1. 上电与复位阶段

STM32 上电后,首先进入 复位状态,这是一种硬件初始化状态,保证芯片的稳定性。复位的方式包括:

  • 上电复位

  • 手动按下 NRST 引脚

  • 软件复位(通过 SCB->AIRCR)

接下来,芯片会读取一个叫做 启动引脚(BOOT0 和 BOOT1) 的组合,用于选择芯片从哪个存储介质启动。

2. 启动模式选择

STM32 支持三种启动模式(以 STM32F103 为例):

BOOT1

BOOT0

启动模式

X

0

从主 Flash 启动

0

1

从系统内置 Bootloader 启动

1

1

从 SRAM 启动

大多数应用情况下,设置为 主 Flash 启动(BOOT0 = 0),也就是我们的应用程序所在位置。

✅ Tips:学习 Bootloader 时,可以手动将 BOOT0 设置为 1,进入 ISP 模式。

3. 读取向量表 & 跳转

无论从哪启动,STM32 都会从特定地址读取 向量表。向量表是中断和异常的入口地址表,前两个条目尤为关键:

  • 地址 0x0000 0000(或其他起始地址):初始主堆栈指针(MSP)

  • 地址 0x0000 0004:复位中断向量(即程序入口地址)

芯片读取这两个值,并进行如下动作:

MSP ← *(0x00000000)PC  ← *(0x00000004)

STM32 会自动把 MSP 设置为初值,然后跳转到复位处理函数,通常是 Reset_Handler()

4. 执行启动文件 startup_xxx.s

Reset_Handler 并不是直接跳到 main(),而是执行一个启动汇编文件,如 startup_stm32f10x.s。它的职责包括:

  • 初始化堆栈指针

  • 初始化中断向量表

  • 调用 SystemInit()(时钟、Flash 等初始化)

  • 初始化数据段(.data)和清零 BSS 段(.bss

  • 最后调用 main()

简化伪代码如下:

​​​​​​​

Reset_Handler:    bl  SystemInit         ; 初始化系统时钟    bl  __libc_init_array  ; C 运行时库初始化    bl  main               ; 跳转到 main 函数


四、C/C++ 运行时初始化详解

在调用 main() 之前,C/C++ 编译器需要做一些关键准备:

✅ .data 段初始化

.data 段是已初始化的全局变量,例如:

int a = 5;  // 存储在 .data

这部分变量的值最初存储在 Flash,需要搬运到 RAM 才能读写。启动文件会将其从 ROM 拷贝到 RAM。

✅ .bss 段清零

.bss 段用于存储未初始化的全局变量,例如:

int b;  // 存储在 .bss,自动清零

启动代码会将 .bss 区域置为 0。

✅ C++ 构造函数支持

如果使用 C++,启动代码还会调用全局构造函数,这是通过 __libc_init_array() 实现的。


五、然后才是我们的 main() 函数

至此,所有底层初始化完成,CPU 跳转到 C 程序的入口 main() 函数,正式交给开发者写业务逻辑。

int main(void){    // 用户应用代码    while (1) {        // 主循环    }}


 


六、动手实践建议(面向初学者)

如果你是 STM32 小白,不妨通过以下步骤深入理解:

  1. 查看启动汇编文件:打开 startup_xxx.s 文件,理解 Reset_Handler 的流程。

  2. 在 SystemInit() 加断点:跟踪是否进入主时钟配置流程。

  3. 使用 map 文件分析段分布:看 .data.bss.text 的地址和大小。

  4. 学习如何修改向量表位置:通过 SCB->VTOR 改变中断表地址。

  5. 尝试裸机启动:不依赖 HAL 库,手动初始化堆栈、中断、系统时钟。


七、总结

STM32 的启动过程虽然隐藏在 HAL 库和 IDE 的自动生成之下,但正是这一套流程,支撑了嵌入式程序的稳定运行。掌握它,不仅有助于开发排错、理解底层逻辑,更是从“会用”到“精通” STM32 的必经之路。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2397156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.RV1126-OPENCV 图像轮廓识别

一.图像识别API 1.图像识别作用 它常用于视觉任务、目标检测、图像分割等等。在 OPENCV 中通常使用 Canny 函数、findContours 函数、drawContours 函数结合在一起去做轮廓的形检测。 2.常用的API findContours 函数:用于寻找图片的轮廓,并把所有的数…

WEB3——开发者怎么查看自己的合约日志记录

在区块链中查看合约的日志信息(也叫事件 logs),主要有以下几种方式,具体方法依赖于你使用的区块链平台(如 Ethereum、BSC、Polygon 等)和工具(如 Etherscan、web3.js、ethers.js、Hardhat 等&am…

TDengine 集群容错与灾备

简介 为了防止数据丢失、误删操作,TDengine 提供全面的数据备份、恢复、容错、异地数据实时同步等功能,以保证数据存储的安全。本节简要说明 TDengine 中的容错与灾备。 容错 TDengine 支持 WAL 机制,实现数据的容错能力,保证数…

MG影视登录解锁永久VIP会员 v8.0 支持手机电视TV版影视直播软件

MG影视登录解锁永久VIP会员 v8.0 支持手机电视TV版影视直播软件 MG影视App电视版是一款资源丰富、免费便捷、且专为大屏优化的影视聚合应用,聚合海量资源,畅享电视直播,是您电视盒子和…

【多线程初阶】内存可见性问题 volatile

文章目录 再谈线程安全问题内存可见性问题可见性问题案例编译器优化 volatileJava内存模型(JMM) 再谈线程安全问题 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该有的结果,则说这个程序是线程安全的,反之,多线程环境中,并发执行后,产生bug就是线程不安全…

C++ 类模板三参数深度解析:从链表迭代器看类型推导与实例化(为什么迭代器类模版使用三参数?实例化又会是怎样?)

本篇主要续上一篇的list模拟实现遇到的问题详细讲解&#xff1a;<传送门> 一、引言&#xff1a;模板参数的 "三角锁钥" 在 C 双向链表实现中&#xff0c;__list_iterator类模板的三个参数&#xff08;T、Ref、Ptr&#xff09;如同精密仪器的调节旋钮&#x…

MySQL强化关键_018_MySQL 优化手段及性能分析工具

目 录 一、优化手段 二、SQL 性能分析工具 1.查看数据库整体情况 &#xff08;1&#xff09;语法格式 &#xff08;2&#xff09;说明 2.慢查询日志 &#xff08;1&#xff09;说明 &#xff08;2&#xff09;开启慢查询日志功能 &#xff08;3&#xff09;实例 3.s…

ASP.NET MVC添加模型示例

ASP.NET MVC高效构建Web应用ASP.NET MVC 我们总在谈“模型”&#xff0c;那到底什么是模型&#xff1f;简单说来&#xff0c;模型就是当我们使用软件去解决真实世界中各种实际问题的时候&#xff0c;对那些我们关心的实际事物的抽象和简化。比如&#xff0c;我们在软件系统中设…

【Part 3 Unity VR眼镜端播放器开发与优化】第二节|VR眼镜端的开发适配与交互设计

文章目录 《VR 360全景视频开发》专栏Part 3&#xff5c;Unity VR眼镜端播放器开发与优化第一节&#xff5c;基于Unity的360全景视频播放实现方案第二节&#xff5c;VR眼镜端的开发适配与交互设计一、Unity XR开发环境与设备适配1.1 启用XR Plugin Management1.2 配置OpenXR与平…

第1天:认识RNN及RNN初步实验(预测下一个数字)

RNN&#xff08;循环神经网络&#xff09; 是一种专门设计用来处理序列数据的人工神经网络。它的核心思想是能够“记住”之前处理过的信息&#xff0c;并将其用于当前的计算&#xff0c;这使得它非常适合处理具有时间顺序或上下文依赖关系的数据。 核心概念&#xff1a;循环连…

树莓派安装openwrt搭建软路由(ImmortalWrt固件方案)

&#x1f923;&#x1f449;我这里准备了两个版本的openwrt安装方案给大家参考使用&#xff0c;分别是原版的OpenWrt固件以及在原版基础上进行改进的ImmortalWrt固件。推荐使用ImmortalWrt固件&#xff0c;当然如果想直接在原版上进行开发也可以&#xff0c;看个人选择。 &…

电子电气架构 --- 如何应对未来区域式电子电气(E/E)架构的挑战?

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

易学探索助手-个人记录(十二)

近期我完成了古籍处理板块页面升级&#xff0c;补充完成原文、句读、翻译的清空、保存和编辑&#xff08;其中句读仅可修改标点&#xff09;功能&#xff0c;新增原文和句读的繁简体切换功能 一、古籍处理板块整体页面升级 将原来一整个页面呈现的布局改为分栏呈现&#xff0…

Python窗体编程技术详解

文章目录 1. Tkinter简介示例代码优势劣势 2. PyQt/PySide简介示例代码(PyQt5)优势劣势 3. wxPython简介示例代码优势劣势 4. Kivy简介示例代码优势劣势 5. PySimpleGUI简介示例代码优势劣势 技术对比总结选择建议 Python提供了多种实现图形用户界面(GUI)编程的技术&#xff0c…

NVMe协议简介之AXI总线更新

更新AXI4总线知识 AXI4总线协议 AXI4总线协议是由ARM公司提出的一种片内总线协议 &#xff0c;旨在实现SOC中各模块之间的高效可靠的数据传输和管理。AXI4协议具有高性能、高吞吐量和低延迟等优点&#xff0c;在SOC设计中被广泛应用 。随着时间的推移&#xff0c;AXI4的影响不…

设计模式——责任链设计模式(行为型)

摘要 责任链设计模式是一种行为型设计模式&#xff0c;旨在将请求的发送者与接收者解耦&#xff0c;通过多个处理器对象按链式结构依次处理请求&#xff0c;直到某个处理器处理为止。它包含抽象处理者、具体处理者和客户端等核心角色。该模式适用于多个对象可能处理请求的场景…

基于Android的医院陪诊预约系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

基于Spring Boot 电商书城平台系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

【金融基础学习】债券回购方式

债券回购作为货币市场的重要工具&#xff0c;本质上是一种以债券为抵押的短期资金借贷行为。在银行间市场&#xff0c;质押式回购与**买断式回购*是两种主要形式。 1. 质押式回购(Pledged Repo, RP) – 所有权不转移的短期融资工具 1.1 质押式回购概述 质押式回购是交易双方…

第五十九节:性能优化-GPU加速 (CUDA 模块)

在计算机视觉领域,实时性往往是关键瓶颈。当传统CPU处理高分辨率视频流或复杂算法时,力不从心。本文将深入探索OpenCV的CUDA模块,揭示如何通过GPU并行计算实现数量级的性能飞跃。 一、GPU加速:计算机视觉的必由之路 CPU的强项在于复杂逻辑和低延迟任务,但面对图像处理中高…