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

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

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 PROCEXPORT Reset_Handler [WEAK]		; WEAK 意思允许其它地方重新定义IMPORT __main                                 ;  声明来自外部的函数IMPORT SystemInitLDR R0, =SystemInit                          ; 调用函数 SystemInitBLX R0LDR R0, =__main                                 ; 调用 __mainBX R0ENDP

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     0x400AREA    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     0x200AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

6. 中断向量表

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


__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault HandlerDCD     MemManage_Handler          ; MPU Fault HandlerDCD     BusFault_Handler           ; Bus Fault HandlerDCD     UsageFault_Handler         ; Usage Fault HandlerDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall HandlerDCD     DebugMon_Handler           ; Debug Monitor HandlerDCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV HandlerDCD     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.lryc.cn/news/496671.html

相关文章:

  • FakeLocation 1.3.5 BETA 提示校园跑漏洞修复解决
  • Figma入门-约束与对齐
  • 腾讯元宝深度搜索AI多线程批量生成TXT原创文章软件
  • Git操作学习1
  • 【计算机网络】细说IP
  • 树与图深度优先遍历——acwing
  • vue3.0 根据富文本html页面生成压缩包(含视频在线地址、图片在线地址、前端截图、前端文档)
  • WPF+LibVLC开发播放器-LibVLC在C#中的使用
  • 消息中间件-Kafka1-实现原理
  • 2023年华数杯数学建模B题不透明制品最优配色方案设计解题全过程文档及程序
  • Mysql事务常见面试题 -- 事务的特性 ,并发事务问题 , undo_log和redo_log , 分布式事务
  • 【数据库系列】Spring Boot如何配置Flyway的回调函数
  • 分布式推理框架 xDit
  • DR.KNOWS:医疗图谱UMLS + 图神经网络 + LLM 模拟医生的诊断推理过程, 从症状出发找到可能的诊断结果
  • 缓存雪崩 详解
  • 使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件
  • Flink随笔 20241203 Flink重点内容
  • shell脚本实战
  • 【机器学习】分类任务: 二分类与多分类
  • FreeSWITCH mod_conference 的按键会控
  • 串口工作方式
  • 统计Nginx的客户端IP,可以通过分析Nginx的访问日志文件来实现
  • Apache Airflow 快速入门教程
  • 42 基于单片机的智能浇花系统
  • 乐橙云小程序插件接入HbuilderX
  • VoCo-LLaMA: Towards Vision Compression with Large Language Models
  • Vue+vite 组件开发的环境准备
  • 基于社区发现的GraphRAG思路
  • react学习记录
  • Day2——需求分析与设计