STM32 HAL库开发学习3.STM32启动浅析

news2025/1/6 20:30:19

STM32 HAL库开发学习3.STM32启动浅析

  • 一、STM32启动模式(也称自举模式)
    • 1. MSP与PC指针赋值
    • 2. F1系列的启动模式:
    • 3. F4系列启动模式
    • 4. F7系列启动模式
    • 5. H7系列启动模式
  • 二、STM32启动过程
    • 1. MSP 栈顶地址
    • 2. PC值
    • 3. Reset_Handler
    • 4. 启动文件内容
    • 5. 堆栈
    • 6. 中断向量表
  • 三、STM32启动过程图解

一、STM32启动模式(也称自举模式)

1. MSP与PC指针赋值

STM32 系列微控制器中的 M3、M4、M7 内核在经历复位操作之后,会率先从特定的内存地址 0x0000 0000 处尝试获取堆栈指针 MSP 的初始值。此初始值具有极为关键的意义,它明确界定了栈顶在内存中的具体位置,为后续程序运行时的函数调用、局部变量存储以及中断处理等操作建立起至关重要的栈空间基础架构。

然后,内核从0x0000 0004处取出程序计数器PC的初始值,该初始值指向的是复位向量所对应的复位处理程序的入口地址(名称为Reset_Handler),这一步明确了程序即将开始执行的具体起始点,使得处理器能够准确地跳转到复位处理程序中,进而开启一系列诸如初始化系统时钟、配置外设、设置中断相关参数等系统初始化操作。

2. F1系列的启动模式:

  1. 系统复位后,SYSCLK的第4个上升沿,BOOT引脚的值锁存;
  2. 启动模式选择引脚。
BOOT1BOOT0启动模式0x00000000映射地址0x00000004映射地址
x0主闪存存储器0x080000000x08000004
01系统存储器, ST Boot Loader0x1FFFF0000x1FFFF004
11内置 SRAM0x200000000x20000000

系统存储器启动时,内嵌的自举程序存放在系统存储区,由ST在生产线上写入,用于通过可用的串行接口对闪存储器进行重新编程。

  • 对于小容量、中容量和大容量的产品而言,可以通过UART1接口启用自举程序。
  • 对于互联型产品而言,可以通过以下某个接口启用自举程序:USART1、USART2(重映像的)、CAN2(重映像的)或USB OTG全速接口的设备模式(通过固件更新DFU协同)。
  • USART接口依靠内部8MHz振荡器(HSI)运行。CAN和USB接口只能当外部8MHz、14.7456MHz或25MHz时钟(HSE)时运行。

3. F4系列启动模式

与F1系列基本一致,注意的是:
如果使用内置 SRAM, 可以使用FSMC重映射到外部的SRAM,可以通过SYSCFG_MEMRMP 寄存器配置。

4. F7系列启动模式

BOOT启动地址选项字节启动模式
0BOOT_ADD0[15:0]由用户选项字节 BOOT_ADD0[15:0] 决定启动地址,ST出厂默认的启动地址为:位于0x0200 0000的ITCM上的FLASH
1BOOT_ADD1[15:0]由用户选项字节 BOOT_ADD1[15:0] 决定启动地址,ST出厂默认的启动地址为:位于0x0010 0000的系统自举程序
Flash选项控制寄存器(FLASH_OPTCR1)----BOOT_ADDx[15:0] 对应地址位 [29:14]
  • BOOT_ADDx = 0x0000: 从 ITCM RAM (0x0000 0000)启动
  • BOOT_ADDx = 0x0040: 从系统存储器 (0x0010 0000) 启动
  • BOOT_ADDx = 0x0080: 从ITCM 接口上的FLASH(0x0020 0000)启动
  • BOOT_ADDx = 0x2000: 从 AXIM 接口上的 FLASH(0x0800 0000)启动
  • BOOT_ADDx = 0x8000: 从 DTCM RAM(0x2000 0000)启动
  • BOOT_ADDx = 0x8004: 从 SRAM1(0x2001 0000)启动
  • BOOT_ADDx = 0x8013: 从 SRAM2(0x2004 C000)启动

x=0/1, 出厂时,BOOT_ADD0=0x0080, BOOT_ADD1 = 0x0040

5. H7系列启动模式

BOOT启动地址选项字节启动模式
0BOOT_ADD0[15:0]由用户选项字节BOOT_ADD0[15:0]决定启动地址,ST出厂默认的启动地址为:0x0800 0000的Flash地址
1BOOT_ADD1[15:0]由用户选项字节 BOOT_ADD1[15:0]决定启动地址,ST出厂默认的启动地址为: 0x1FF0 0000的系统存储器地址

二、STM32启动过程

以内部Flash启动为例。

1. MSP 栈顶地址

当芯片配置为从主闪存启动(例如 BOOT0 = 0,BOOT1 = x)时,存储控制器会自动将起始地址 0x00000000 映射到主闪存的起始物理地址(通常是 0x08000000)。这是通过芯片内部的硬连线和一些基本的逻辑电路来实现的,这些电路会根据启动模式引脚(BOOT0 和 BOOT1)的状态来确定初始的地址映射关系。

这是MSP值就是 0x0800 0000。

2. PC值

内核第二步获取PC的初始值。 这个PC的初始值指向的就是 Reset_Handler。
Reset_Handler定义在启动文件: startup_stm32xxx.S 里。

3. Reset_Handler

Reset_Handler执行一些初始化,再去调用 main函数。

Reset_Handler PROC
    EXPORT Reset_Handler [WEAK]		; WEAK 意思允许其它地方重新定义
    IMPORT __main                                 ;  声明来自外部的函数
    IMPORT SystemInit
    LDR R0, =SystemInit                          ; 调用函数 SystemInit
    BLX R0
    LDR R0, =__main                                 ; 调用 __main
    BX R0
    ENDP

4. 启动文件内容

  1. 初始化MSP 指针 从 0x0800 0000 获取
  2. 初始化PC 从0x0800 0004 获取
  3. 设置堆栈大小 Heap_Size(堆), Stack_Size(栈)
  4. 初始化中断向量表 __Vectors 定义
  5. 调用初始化函数,可选的,如调用 SystemInit 函数
  6. 调用 __main
  7. 调用 main

5. 堆栈

  1. 栈(Stack):由编译器自动分配和释放,存放函数参数、局部变量等
  2. 堆(Heap):由malloc,calloc,realloc等 程序分配和释放
Stack_Size		EQU     0x400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size      EQU     0x200

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

6. 中断向量表

从__Vectors 里开始。
中断向量表里面的很多个DCD结构。


__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts

由于 __initial sp是指向 0x0800 0000,后面每一项偏移4个字节。
每一项是一个函数名,(函数名就是函数的地址)。

三、STM32启动过程图解

在这里插入图片描述
从图上可以看出,启动时从0x0800 0000获取 MSP地址,就是栈顶地址,即: 0x2000 0788。
然后 0x0800 0004放的是PC指针,程序到 0x0800 01CD执行引导代码,即Reset_Hander函数。
对于这些地址值,在 .map 文件里也可以找到其地址。

本文学习资源来自 正点原子HAL开发 官方教程。

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

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

相关文章

FCBP 认证考试要点摘要

理论知识 数据处理与分析&#xff1a;包括数据的收集、清洗、转换、存储等基础操作&#xff0c;以及数据分析方法&#xff0c;如描述性统计分析、相关性分析、数据挖掘算法等的理解和应用 。数据可视化&#xff1a;涉及图表类型的选择与应用&#xff0c;如柱状图、折线图、饼图…

xv6前置知识

fork函数 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。 一个进程调用fork()函数后,系统先给新的进程分…

ECharts柱状图-极坐标系下的堆叠柱状图,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…

监控视频汇聚平台:Liveweb视频监控管理平台方案详细介绍

Liveweb国标视频综合管理平台是一款以视频为核心的智慧物联应用平台。它基于分布式、负载均衡等流媒体技术进行开发&#xff0c;提供广泛兼容、安全可靠、开放共享的视频综合服务。该平台具备多种功能&#xff0c;包括视频直播、录像、回放、检索、云存储、告警上报、语音对讲、…

MySQL源码编译

华子目录 下载源码包上传并解压安装cmake环境检测make编译make install安装 部署复制编译文件到别的主机上 下载源码包 下载相应源码包mysql5.7编译安装需要boost库&#xff0c;这里官网下载含boost的源码包https://downloads.mysql.com/archives/community/ 上传并解压 [roo…

请求(request)

目录 前言 request概述 request的使用 获取前端传递的数据 实例 请求转发 特点 语法 实例 实例1 实例2 【关联实例1】 域对象 组成 作用范围&#xff1a; 生命周期&#xff1a; 使用场景&#xff1a; 使用步骤 存储数据对象 获得数据对象 移除域中的键值…

推荐学习笔记:矩阵补充和矩阵分解

参考&#xff1a; 召回 fun-rec/docs/ch02/ch2.1/ch2.1.1/mf.md at master datawhalechina/fun-rec GitHub 业务 隐语义模型与矩阵分解 协同过滤算法的特点&#xff1a; 协同过滤算法的特点就是完全没有利用到物品本身或者是用户自身的属性&#xff0c; 仅仅利用了用户与…

构造函数与析构函数错题汇总

构造函数不能定义返回类型&#xff0c;也没有返回类型。 堆、栈、静态存储区。栈上的对象main函数结束就释放&#xff0c;堆上的需要手动释放&#xff0c;静态存储区的在所在作用域的程序结束时释放。这里static在main函数内&#xff0c;是局部变量&#xff0c;所以作用域为…

[免费]SpringBoot+Vue景区订票(购票)系统【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue大景区订票(购票)系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue景区订票(购票)系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 现代经济快节奏发展以及不断完善升级的信息…

fastdds:编译、安装并运行helloworld

fastdds安装可以参考官方文档&#xff1a; 3. Linux installation from sources — Fast DDS 3.1.0 documentation 从INSTALLATION MANUAL这一节可以看出来&#xff0c;fastdds支持的操作系统包括linux、windows、qnx、MAC OS。本文记录通过源码和cmake的方式来安装fastdds的…

HTTP 探秘之旅:从入门到未来

文章目录 导言&#xff1a;目录&#xff1a;第一篇&#xff1a;HTTP&#xff0c;互联网的“快递员”第二篇&#xff1a;从点开网页到看到内容&#xff0c;HTTP 究竟做了什么&#xff1f;第三篇&#xff1a;HTTP 的烦恼与进化史第四篇&#xff1a;HTTP 的铠甲——HTTPS 的故事第…

【软件项目测试文档大全】软件测试方案,验收测试计划,验收测试报告,测试用例,集成测试,测试规程和指南,等保测试(Word原件)

1. 引言 1.1. 编写目的 1.2. 项目背景 1.3. 读者对象 1.4. 参考资料 1.5. 术语与缩略语 2. 测试策略 2.1. 测试完成标准 2.2. 测试类型 2.2.1. 功能测试 2.2.2. 性能测试 2.2.3. 安全性与访问控制测试 2.3. 测试工具 3. 测试技术 4. 测试资源 4.1. 人员安排 4.…

前端拿不到 response 响应流返回的 header 例如 Content-Disposition 等

同步发布于我的网站 &#x1f680; 背景介绍默认可访问的响应头问题分析解决方案 示例 前端代码示例注意事项总结 背景介绍 在进行前后端交互时&#xff0c;前端有时需要读取服务器返回的特定响应头&#xff08;如 Content-Disposition&#xff09;&#xff0c;以便根据这些…

SQL进阶——C++与SQL进阶实践

在C开发中&#xff0c;SQL数据库的操作是开发者常见的任务之一。虽然前面我们已经介绍了如何在C中通过数据库连接执行基本的SQL查询&#xff0c;但在实际项目中&#xff0c;我们通常需要更加复杂和高效的数据库操作。存储过程与函数的调用、复杂SQL查询的编写、以及动态构造SQL…

论文概览 |《Urban Analytics and City Science》2023.05 Vol.50 Issue.4

本次给大家整理的是《Environment and Planning B: Urban Analytics and City Science》杂志2023年5月第50卷第4期的论文的题目和摘要&#xff0c;一共包括19篇SCI论文&#xff01; 论文1 Data analytics and sustainable urban development in global cities 全球城市的数据…

HarmonyOS4+NEXT星河版入门与项目实战(24)------Stage模型

文章目录 1、概念2、配置文件1、全局配置文件2、模块配置文件3、UIAbility生命周期1、图文归纳2、生命周期方法入口4、页面生命周期1、图文描述1、概念 2、配置文件 1、全局配置文件 2、模块配置文件 统一修改配置文件技巧:点击任意json 文件,选择 Open editor ,在显示的列表…

kubernetes——part3-2 集群声明式文件YAML

一、YAML介绍 YAML 的意思是&#xff1a;仍是一种标记语言&#xff0c;但为了强调这种语言以数据做为中心&#xff0c;而不是以标记语言为重点。是一个可读性高&#xff0c;用来表达数据序列的格式。 二、基本语法 1.低版本缩进时不允许使用Tab键&#xff0c;只允许使用空格…

告别 Kafka,拥抱 Databend:构建高效低成本的用户行为分析体系

用户行为数据埋点指标是数据仓库中不可或缺的重要数据源之一&#xff0c;同时也是企业最宝贵的资产之一。通常情况下&#xff0c;用户行为数据分析包含两大数据源&#xff1a;用户行为分析日志和上游关系型数据库&#xff08;如 MySQL&#xff09;。基于这些数据&#xff0c;企…

产出一篇论文的各个步骤

产出一篇论文的各个步骤 建议–实用 如何看论文&#xff1a; &#xff08;前提&#xff1a;优秀论文&#xff0c;如顶会论文/杂志&#xff0c;了解顶会是那些&#xff0c;召开时间是什么时候&#xff09; 创新点 记录下来说过的别的文章/方法的缺陷 – 看文章就是看优点/指出…

AtomicIntegerFieldUpdater能否降低内存

1. 代码如下&#xff1a; import java.util.LinkedList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerTest {final AtomicInteger startPosition new AtomicInteger(0);final AtomicInteger wrotePosition new Atom…