STM32启动流程详解
STM32启动流程详解
本文档详细介绍STM32微控制器从上电到main函数执行的完整启动流程。
1. 上电与复位过程
当STM32芯片上电或复位时,硬件会执行以下步骤:
- 上电复位(POR)/低电平复位(PDR): 芯片接通电源或NRST引脚置低时触发
- 初始PC值设置: 程序计数器(PC)被设置为0x00000000
- 首地址读取: CPU从地址0x00000000读取栈顶指针(MSP)的值
- 向量表读取: CPU从地址0x00000004读取复位向量(Reset_Handler的地址),并跳转执行
2. 启动文件执行流程
启动文件(startup_stm32f103xb.s)是STM32启动过程的关键部分,主要执行以下操作:
Reset_Handler:ldr r0, =_estack ; 加载栈顶指针到r0寄存器mov sp, r0 ; 设置栈指针; 初始化数据段ldr r0, =_sdata ; 加载数据段目标起始地址ldr r1, =_edata ; 加载数据段目标结束地址ldr r2, =_sidata ; 加载数据段源起始地址(Flash中)movs r3, #0b LoopCopyDataInit; ... 数据段复制循环 ...; 初始化BSS段(清零)ldr r2, =_sbss ; 加载BSS段起始地址ldr r4, =_ebss ; 加载BSS段结束地址movs r3, #0b LoopFillZerobss; ... BSS段清零循环 ...bl SystemInit ; 调用SystemInit函数初始化系统时钟bl __libc_init_array ; 调用C库初始化函数bl main ; 调用main函数bx lr ; 返回(实际上main函数不会返回)
3. 向量表
向量表定义在启动文件中,存储在Flash起始位置,包含:
- 栈顶指针(MSP): 向量表第一项是主栈指针初始值
- 复位向量: Reset_Handler函数地址
- 异常向量: 各种异常处理函数的地址(NMI、HardFault等)
- 中断向量: 外设中断处理函数的地址
__Vectors:.word _estack ; 栈顶指针.word Reset_Handler ; 复位处理函数.word NMI_Handler ; NMI处理函数.word HardFault_Handler ; 硬件错误处理函数; ... 其他异常和中断向量 ...
4. SystemInit函数详解
SystemInit函数定义在system_stm32f1xx.c文件中,主要负责系统时钟配置:
void SystemInit(void)
{/* 重置RCC时钟配置为默认复位状态 *//* 设置HSION位 */RCC->CR |= 0x00000001U;/* 复位SW、HPRE、PPRE1、PPRE2、ADCPRE和MCO位 */RCC->CFGR &= 0xF8FF0000U;/* 复位HSEON, CSSON和PLLON位 */RCC->CR &= 0xFEF6FFFFU;/* 复位HSEBYP位 */RCC->CR &= 0xFFFBFFFFU;/* 复位PLLSRC, PLLXTPRE, PLLMUL和USBPRE位 */RCC->CFGR &= 0xFF80FFFFU;/* 禁用所有中断 */RCC->CIR = 0x00000000U;#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* 若向量表在SRAM中 */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* 向量表在Flash中 */
#endif
}
主要功能:
- 配置系统时钟回到默认状态(通常使用内部RC振荡器HSI,8MHz)
- 设置向量表偏移地址(VTOR寄存器)
5. C库初始化
__libc_init_array()函数负责调用所有构造函数并初始化C/C++运行环境:
- 调用
.preinit_array段中的所有函数 - 调用
.init_array段中的所有函数 - 初始化全局变量和静态变量

我找了一下,在这里。反汇编代码如下。

这是__libc_init_array函数的ARM汇编代码:
这个函数负责在main函数执行前初始化C/C++运行时环境,具体执行两个主要任务:
第一部分(处理.preinit_array段)
0-14: 保存寄存器并加载.preinit_array段的起始和结束地址
18-1c: 初始化循环计数器,计算数组元素数量(将字节差除以4)
24-38: 循环遍历.preinit_array中的每个函数指针并调用:- 加载函数指针到r3- 更新计数器- 通过bx指令调用函数- 比较是否已处理完所有函数
中间调用_init函数
3c: bl _init // 调用标准的初始化函数
第二部分(处理.init_array段)
40-54: 加载.init_array段的起始和结束地址,计算元素数量
58-74: 循环遍历.init_array中的每个函数指针并调用,过程与第一部分类似
结束处理
78-7c: 恢复保存的寄存器并返回
这个函数的主要作用是:
- 调用所有注册在.preinit_array段的预初始化函数
- 调用系统的_init函数
- 调用所有注册在.init_array段的初始化函数(包括全局C++对象的构造函数)
这样确保了在main函数开始执行前,所有必要的全局对象和C/C++运行时环境都已正确初始化。
6. main函数执行
在完成上述所有初始化步骤后,启动代码通过bl main指令跳转到用户定义的main函数,开始执行应用程序代码。
7. 数据段和BSS段
- 数据段(.data): 已初始化的全局变量和静态变量,从Flash复制到RAM
- BSS段(.bss): 未初始化的全局变量和静态变量,在RAM中清零
8. 启动流程总结
上电/复位 → 加载MSP → 跳转到Reset_Handler → 初始化栈指针 →
复制.data段 → 清零.bss段 → SystemInit() → __libc_init_array() → main()
9. STM32启动流程的优化与自定义
在实际项目中,可以通过以下方式优化或自定义启动流程:
- 修改启动文件以支持特定的内存布局
- 自定义SystemInit函数实现特定的时钟配置
- 在main函数之前添加自定义的初始化代码
通过理解这一完整的启动过程,开发者可以更好地控制STM32应用程序的初始化行为,优化系统性能,并解决启动相关的问题。
相关文章:
STM32启动流程详解
STM32启动流程详解 本文档详细介绍STM32微控制器从上电到main函数执行的完整启动流程。 1. 上电与复位过程 当STM32芯片上电或复位时,硬件会执行以下步骤: 上电复位(POR)/低电平复位(PDR): 芯片接通电源或NRST引脚置低时触发初始PC值设置: 程序计数器…...
Langchain + Gemini API调用基本操作
本文参考Langchain中ChatGoogleGenerativeAI的官方文档,在本地的jupyter notebook中运行。 关于API的细节在官方文档最开头给出: 我们在使用时,可以选择model"gemini-2.0-flash-001"或者生成图片的ChatGoogleGenerativeAI(model“…...
利用 Python 和 AI 技术创作独特的图像艺术作品
1. 项目目标 生成艺术作品:利用 AI 模型(如 Stable Diffusion)生成具有艺术风格的图像。自定义风格:通过文本提示(prompt)控制图像的艺术风格(如赛博朋克、印象派、超现实主义等)。…...
Matlab绘图(三)——设置图例的位置
❤️1. 使用 Location 参数设置图例位置 h_legend legend({系列 A, 系列 B, 系列 C}, ...FontName, Arial, ... % 指定字体名称FontSize, 10, ... % 指定字体大小Location, northeast); % 指定初始位置在右上角调用 legend 函数,并通过 Location 参数指定图例放…...
【数据结构】4.单链表实现通讯录
在上一篇文章我们学会了用单链表来实现各种方法,在这一篇文章我们将在单链表的基础上实现通讯录。 0、准备工作 实现通讯录之前,我们还需要在单链表的基础上添加2个文件,头文件Contact.h和源文件Contact.c。Contact.c来实现通讯录方法的声明…...
接口自动化测试(一)
一、HTTP请求的核心概念及原理详解 HTML:超文本标记语言-----通过<标记符>内容</标记符>格式-------页面 URL:统一资源定位符 返回数据有很多:页面、图片、视频,都可以进行返回---统称为:资源HTTP:超文本传输协议(请求-响应的协…...
【JavaEE】Spring AOP的注解实现
目录 一、AOP 与 Spring AOP二、Spring AOP简单实现三、详解Spring AOP3.1 Spring AOP 核心概念3.1.1 切点(Pointcut)3.1.2 连接点(Join Point)3.1.3 通知(Advice)3.1.4 切面(Aspect)…...
从零开始实现 MobileViT 注意力机制——轻量级Transformer Vision Model 的新思路
从零开始实现 MobileViT 注意力机制——轻量级Transformer Vision Model 的新思路 近年来,计算机视觉领域中 Transformer 模型的崛起为图像处理带来了新的活力。特别是在 ViT(Vision Transformer)模型提出之后,Transformer 在图像…...
揭秘大数据 | 22、软件定义存储
揭秘大数据 | 19、软件定义的世界-CSDN博客 揭秘大数据 | 20、软件定义数据中心-CSDN博客 揭秘大数据 | 21、软件定义计算-CSDN博客 老规矩,先把这个小系列的前三篇奉上。今天书接上文,接着叙软件定义存储的那些事儿。 软件定义存储源于VMware公司于…...
OpenCV 图形API(37)图像滤波-----分离过滤器函数sepFilter()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 应用一个可分离的线性滤波器到一个矩阵(图像)。 该函数对矩阵应用一个可分离的线性滤波器。也就是说,首先&a…...
flutter下载SDK环境配置步骤详解
目录 1.Flutter官网地址、SDK下载地址? 1.1 选择你电脑的系统 2.配置环境 3.解决环境报错 zsh:command not found:flutter 1.Flutter官网地址、SDK下载地址? flutter官网地址: URL 1.1 选择你电脑的系统 下载解压动目录就OK了 2.配置环境 1、打开命令行…...
数据结构与算法入门 Day 0:程序世界的基石与密码
🌟数据结构与算法入门 Day 0:程序世界的基石与密码🔑 ps:接受到了不少的私信反馈,说应该先把前置的知识内容做一个梳理,所以把昨天的文章删除了,重新开启今天的博文写作 Hey 小伙伴们ÿ…...
vscode终端运行windows服务器的conda出错
远程windows服务器可以运行,本地vscode不能。 打开vscode settings.json文件 添加conda所在路径...
Elasticsearch 查询排序报错总结
Elasticsearch 查询sort报错总结 文章目录 Elasticsearch 查询`sort`报错总结错误1、使用Es对 `sort` 进行排序字段类型的要求1.1、数值类型(如 `integer`、`long`、`float`、`double`)1.2、日期类型(如 `date`)1.3、字符串类型(如 `keyword`、`text`)1.4、布尔类型(`bo…...
“大湾区珠宝艺境花园”璀璨绽放第五届消博会
2025年4月13日,第五届中国国际消费品博览会(以下简称"消博会")重要主题活动——《大湾区珠宝艺境花园》启动仪式在海南国际会展中心2号馆隆重举行。由广东省金银珠宝玉器业厂商会组织带领粤港澳大湾区优秀珠宝品牌,以“…...
十、自动化函数+实战
Maven环境配置 1.设计测试用例 2.创建空项目 1)添加需要的依赖pom.xml <dependencies> <!-- 截图配置--><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</…...
Day09【基于jieba分词和RNN实现的简单中文分词】
基于jieba分词和RNN实现的中文分词 目标数据准备主程序预测效果 目标 本文基于给定的中文词表,将输入的文本基于jieba分词分割为若干个词,词的末尾对应的标签为1,中间部分对应的标签为0,同时将分词后的单词基于中文词表做初步序列…...
自动化测试——selenium
简介 Selenium 是一个广泛使用的自动化测试工具,主要用于 Web 应用程序的自动化测试。它能实现的功能是网页的自动化操作,例如自动抢票刷课等。同时你应该也见到过有些网站在打开之后并没有直接加载出网站的所有内容,比如一些图片等等&#x…...
java和python实现mqtt
说明: MQTT 异步通信系统功能文档 系统概述 本系统基于 MQTT 协议实现异步通信,包含三个核心组件: Broker(消息代理):负责消息的路由和转发。 Client(主客户端):定时发…...
5.9 《GPT-4调试+测试金字塔:构建高可靠系统的5大实战策略》
5.4 测试与调试:构建企业级质量的保障体系 关键词:测试金字塔模型、GPT-4调试助手、LangChain调试模式、异步任务验证 测试策略设计(测试金字塔实践) #mermaid-svg-RblGbJVMnCIShiCW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill…...
Linux——进程通信
我们知道,进程具有独立性,各进程之间互不干扰,但我们为什么还要让其联系,建立通信呢?比如:数据传输,资源共享,通知某个事件,或控制某个进程。因此,让进程间建…...
学习笔记十三—— 理解 Rust 闭包:从语法到 impl Fn vs Box<dyn Fn>
🧠 理解 Rust 闭包:从语法到 impl Fn vs Box 📚 目录 闭包是什么?和普通函数有什么不同?闭包的语法长什么样?闭包“捕获变量”是什么意思?闭包和所有权的关系Fn、FnMut、FnOnce 三种闭包类型的…...
【免费参会合集】2025年生物制药行业展会会议表格整理
全文精心整理, 建议今年参会前都好好收藏着,记得点赞! 医药人非常吃资源,资源从何而来?作为一名从事医药行业的工作者,可以很负责任的告诉诸位,其中非常重要的一个渠道就是会议会展! 建议所有医…...
腾讯云开发+MCP:旅游规划攻略
1.登录注册好之后进入腾讯云开发 2.创建环境 4.创建好环境之后点击去开发 5.进入控制台后,选择AI,找到MCP 6.点击创建MCP Server 使用腾讯云开发创建MCP目前需要云开发入门版99/月,我没开通,所以没办法往下进行。...
银河麒麟系统 达梦8 安装 dlask 框架后端环境
适配的一套环境为 dmPython2.5.8 dmSQLAlchemy1.4.39 Flask2.0.3 Flask-Cors3.0.10 Flask-SQLAlchemy2.5.1 SQLAlchemy1.4.54 Werkzeug2.2.2其中 # sqlalchemy-dm1.4.39 通过dmdbms目录内文件进行源码安装 (MindSpore) [ma-user python]$pwd /home/syl/dmdbms/drivers/python…...
Cribl (实验) vpc-flow 数据抽样
先看文档: Firewall Logs: VPC Flow Logs, Cisco ASA, Etc. | Cribl Docs Firewall Logs: VPC Flow Logs, Cisco ASA, Etc. Recipe for Sampling Firewall Logs Firewall logs are another source of important operational (and security) data. Typical examples include Ama…...
Sklearn入门之数据预处理preprocessing
、 Sklearn全称:Scipy-toolkit Learn是 一个基于scipy实现的的开源机器学习库。它提供了大量的算法和工具,用于数据挖掘和数据分析,包括分类、回归、聚类等多种任务。本文我将带你了解并入门Sklearn下的preprocessing在机器学习中的基本用法。 获取方式…...
我想自己组装一台服务器,微调大模型通义千问2.5 Omni 72B,但是我是个人购买,资金非常有限,最省的方案
目录 🧠 首先我们要搞清楚几个核心点: 🎯 目标:微调 Qwen2.5-Omni-72B 🚨 现实问题:作为个人用户,72B 模型几乎无法负担全量微调 💸 全量微调硬件需求: ✅ 最省的个人方案:不组 72B,只训练 Qwen2.5-Omni-7B 或 14B 💡 推荐方案 A:个人桌面级多卡训练服…...
家用打印机性价比排名及推荐
文章目录 品牌性价比一、核心参数对比与场景适配二、技术类型深度解析三、不同场景选择 相关文章 品牌 性价比 一、核心参数对比与场景适配 兄弟T436W 优势: 微压电技术,打印头寿命长,堵头率低。 支持A4无边距和5G WiFi,适合照片…...
KWDB(Knowledge Worker Database)基础概念与原理完整指南
KWDB(Knowledge Worker Database)基础概念与原理完整指南—目录 前言一、背景1.1 知识工作者的痛点1.2 技术演进推动 二、定义与定位2.1 什么是KWDB?2.2 KWDB与传统数据库的对比与传统关系型数据库(如MySQL)的对比与分…...
