当前位置: 首页 > article >正文

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

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

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 的必经之路。

相关文章:

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

一、为什么要理解启动过程? STM32 的启动过程就像一台精密仪器的开机自检,它确保所有系统部件按既定方式初始化,才能顺利运行我们的应用代码。对初学者而言,理解启动过程能帮助解决常见“程序跑飞”“不进 main”“下载后无反应”…...

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电视版是一款资源丰富、免费便捷、且专为大屏优化的影视聚合应用,聚合海量资源,畅享电视直播,是您电视盒子和…...

如何成为一名优秀的产品经理(自动驾驶)

一、 夯实核心基础 深入理解智能驾驶技术栈: 感知: 摄像头、雷达(毫米波、激光雷达)、超声波传感器的工作原理、优缺点、融合策略。了解目标检测、跟踪、SLAM等基础算法概念。 定位: GNSS、IMU、高精地图、轮速计等定…...

BAT脚本编写详细教程

目录 第一部分:BAT脚本简介第二部分:创建和运行BAT脚本第三部分:基本命令和语法第四部分:变量使用第五部分:流程控制第六部分:函数和子程序第七部分:高级技巧第八部分:实用示例第一部分:BAT脚本简介 BAT脚本(批处理脚本)是Windows操作系统中的一种脚本文件,扩展名…...

快速了解 GO之接口解耦

更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…...

【多线程初阶】内存可见性问题 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;循环连…...

全文索引详解及适用场景分析

全文索引详解及适用场景分析 1. 全文索引基本概念 1.1 定义与核心原理 全文索引(Full-Text Index)是一种特殊的数据库索引类型,专门设计用于高效处理文本数据的搜索需求。与传统的B树索引不同,全文索引不是基于精确匹配,而是通过建立倒排索引(Inverted Index)结构来实现对…...

利用DeepSeek编写能在DuckDB中读PostgreSQL表的表函数

前文实现了UDF和UDAF&#xff0c;还有一类函数是表函数&#xff0c;它放在From 子句中&#xff0c;返回一个集合。DuckDB中已有PostgreSQL插件&#xff0c;但我们可以用pqxx库实现一个简易的只读read_pg()表函数。 提示词如下&#xff1a; 请将libpqxx库集成到我们的程序&#…...

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

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

排序算法——详解

排序算法 &#xff08;冒泡、选择、插入、快排、归并、堆排、计数、桶、基数&#xff09; 稳定性 (Stability): 如果排序算法能保证&#xff0c;当待排序序列中存在值相等的元素时&#xff0c;排序后这些元素的相对次序保持不变&#xff0c;那么该算法就是稳定的。 例如&#…...

Go整合Redis2.0发布订阅

Go整合Redis2.0发布订阅 Redis goredis-cli --version redis-cli 5.0.14.1 (git:ec77f72d)Go go get github.com/go-redis/redis/v8package redisimport ("MyKindom-Server-v2.0/com/xzm/core/config/yaml""MyKindom-Server-v2.0/com/xzm/core/config/yaml/po…...

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

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

鸿蒙OS基于UniApp的区块链钱包开发实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapp

基于UniApp的区块链钱包开发实践&#xff1a;打造支持鸿蒙生态的Web3应用 前言 最近在带领团队开发一个支持多链的区块链钱包项目时&#xff0c;我们选择了UniApp作为开发框架。这个选择让我们不仅实现了传统移动平台的覆盖&#xff0c;还成功将应用引入了快速发展的鸿蒙生态…...

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

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

Windows 账号管理与安全指南

Windows 账号管理与安全指南 概述 Windows 账号管理是系统安全的基础&#xff0c;了解如何正确创建、管理和保护用户账户对于系统管理员和安全专业人员至关重要。本文详细介绍 Windows 系统中的账户管理命令、隐藏账户创建方法以及安全防护措施。 基础账户管理命令 net use…...

Python窗体编程技术详解

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

思维链提示:激发大语言模型推理能力的突破性方法

论文出处&#xff1a; Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 作者&#xff1a; Jason Wei, Xuezhi Wang, Dale Schuurmans, Maarten Bosma, Brian Ichter, Fei Xia, Ed H. Chi, Quoc V. Le, Denny Zhou 机构&#xff1a; Google Research, B…...

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 质押式回购概述 质押式回购是交易双方…...