STM32的启动流程

启动模式

我们知道的复位方式有三种:上电复位,硬件复位和软件复位。当产生复位,并且离开复位状态后, CM33 内核做的第一件事就是读取下列两个 32 位整数的值:

(1) 从地址 0x0000 0000 处取出堆栈指针 MSP 的初始值,该值就是栈顶地址。

(2) 从地址 0x0000 0004 处取出程序计数器指针 PC 的初始值, 该值指向复位后执行的第一条指令。下面用示意图表示,如图所示。

上述过程中,内核是从 0x0000 0000 和 0x0000 0004 两个的地址获取堆栈指针 SP 和程序计数器指针 PC。 事实上, 0x0000 0000 和 0x0000 0004 两个的地址可以被重映射到其他的地址空间。 例如: 我们将 0x0800 0000 映射到 0x0000 0000,即从内部 FLASH 启动, 那么内核会从地址 0x0800 0000 处取出堆栈指针 MSP 的初始值,从地址 0x0800 0004 处取出程序计数器指针PC 的初始值。 CPU 会从 PC 寄存器指向的地址空间取出的第 1 条指令开始执行程序,就是开始执行复位中断服务程序 Reset_Handler。

将 0x0000 0000 和 0x0000 0004 两个的地址重映射到其它地址空间,就是启动模式选择。对于 STM32H5 的启动模式(也称自举模式),我们看表 进行分析。

2, 启动引脚(BOOT0) 的电平: 0:低电平; 1:高电平。

由表可以看到, STM32H5的启动地址是由BOOT0引脚电平状态和NSBOOTADD[31:8]或 SECBOOTADD[31:8]选项字节共同决定的。 它们总共可以分为 4 个组合,下面分别来介绍一下:

1,产品状态在 Open 的情况下, BOOT0 引脚电平为低时,启动地址由用户选项字节NSBOOTADD[31:8]来决定。 ST 出厂默认的启动地址为 0x0800 0000, 这个情况就是我们最常用的了。

2,产品状态在任意模式下, BOOT0 引脚电平为高时,用户选项字节 NSBOOTADD[31:8]此时不起作用,启动地址在 ST 官方的 Bootloader 程序开始启动。此时可以用 ST 官方默认的接口,如: USART、 I2C、 I3C、 SPI、 FDCAN、 USB_FS 等下载程序。

3,产品状态在 Provisioning 的情况下, 此时 BOOT0 引脚和用户选项字节 NSBOOTADD[31:8]不起作用, 程序从 RSS(根安全服务) 启动。

4,产品状态在 Provisioned、 Closed、 Locked 的情况下, BOOT0 引脚电平为低时,启动地址由用户选项字节 NSBOOTADD[31:8]来决定, ST 出厂默认的启动地址是 0x0800 0000。

启动文件分析

STM32 启动文件由 ST 官方提供,在官方的 STM32Cube 固件包里,对于 STM32H562 系列芯片的启动文件,我们选用的是 startup_stm32h562xx.s 这个文件。 启动文件用汇编编写,是系统上电复位后第一个执行的程序。启动文件主要做了以下工作:

1、初始化堆栈指针 SP = _initial_sp

2、初始化程序计数器指针 PC = Reset_Handler

3、设置堆和栈的大小

4、初始化中断向量表

5、配置外部 SRAM 作为数据存储器(可选)

6、配置系统时钟,通过调用 SysteMinit 函数(可选)

7、调用 C 库中的 _main 函数初始化用户堆栈,最终调用 main 函数

启动文件中的一些指令

上表,列举了 STM32 启动文件的一些汇编和编译器指令

启动文件代码讲解

(1)栈空间的开辟栈空间的开辟

源码含义:开辟一段大小为 0x0000 0800(2KB)的栈空间, 段名为 STACK,

NOINIT 表示不初始化;

READWRITE 表示可读可写; ALIGN=3,表示按照 2^3 对齐,即 8 字节对齐。

AREA 汇编一个新的代码段或者数据段。SPACE 分配内存指令,分配大小为 Stack_Size 字节连续的存储单元给栈空间。__initial_sp 紧挨着 SPACE 放置,表示栈的结束地址,栈是从高往低生长,所以结束地址就是栈顶地址。

栈主要用于存放局部变量,函数形参等,属于编译器自动分配和释放的内存,栈的大小不能超过内部 SRAM 的大小

### STM32微控制器启动过程详解 STM32 是基于 ARM Cortex-M 架构的微控制器系列,其启动过程涉及硬件初始化和软件执行两个主要阶段。以下是关于 STM32 启动过程的具体描述: #### 1. 上电复位与 Boot 模式选择 当 STM32 微控制器上电或发生复位事件时,内部硬件电路会自动进入复位状态。此时,微控制器的核心寄存器被设置为其默认值,同时系统会选择从哪个存储区域加载初始指令。 Boot 模式的选择由引脚 `BOOT0` 和 `BOOT1` 的组合决定[^1]。具体来说: - 如果 `BOOT0=0` 并且 `BOOT1=x`,则设备将从 Flash 存储器启动。 - 如果 `BOOT0=1` 并且 `BOOT1=0`,则设备将从 System Memory 启动。 - 如果 `BOOT0=1` 并且 `BOOT1=1`,则设备将从 SRAM 启动。 这种模式的选择允许开发者灵活地指定不同的启动源,例如运行预置的 bootloader 或者调试代码。 #### 2. 系统时钟配置 在完成 Boot 模式选择之后,STM32 进一步初始化系统时钟。默认情况下,微控制器会在复位后使用内部 RC 振荡器 (HSI) 作为系统时钟源。随后,可以通过修改 RCC(Reset and Clock Control)寄存器来切换至外部晶振 (HSE),并启用 PLL 来提高主频以达到最佳性能[^1]。 #### 3. 堆栈指针初始化 一旦选择了正确的时钟源,堆栈指针 (`SP`) 就会被初始化为链接器文件中定义的位置。该地址位于向量表的第一个条目处,而向量表本身通常驻留在闪存起始位置或者重新映射后的 RAM 地址范围内[^1]。 #### 4. 跳转到主函数入口点 紧接着,在向量表中的第二个条目保存着 Reset Handler 函数的地址。CPU 控制权转移至此函数,标志着正式进入了用户编写的程序逻辑部分。一般而言,Reset Handler 定义了一系列必要的低级初始化操作,比如 GPIO 设置、外设使能以及中断优先级分配等[^3]。 ```c void Reset_Handler(void) { // 初始化堆栈和其他环境变量 __initialize_hardware(); // 调用 C 库初始化例程 _SystemInit(); // 开始执行 main() 函数 main(); } ``` 以上即构成了整个 STM32 微控制器完整的启动流程概述。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦梨甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值