STM32在进入main函数之前的准备工作

在大部分嵌入式系统中,在进入main函数之前都需要执行一个系统 初始化序列。这里所说的初始化序列特指的是软件运行环境的初始化。

在这里插入图片描述

上图是系统开始运行后,在进入main函数之前的默认初始化序列。从图中可以看出,在左侧有2个函数:__main()__rt_entry() 。这两个函数都属于C语言的库函数。__main() 函数是默认的C语言库函数的入口函数,然后__main() 函数会调用__rt_entry() 函数,在__rt_entry() 函数中再调用main() 函数。函数的层级关系见下图所示。

在这里插入图片描述

__main函数

因为编译生成的固件是下载到ROM中的,但是在系统运行的时候变量是在RAM中的,因此在系统上电之后,首先要将相关的全局变量等数据从ROM复制到RAM中。__main() 函数的主要功能就是将全局变量复制到RAM中。全局变量分2类:有初值的(RW变量)和初值为0的(ZI变量)。

在这里插入图片描述

__rt_entry函数

__main() 函数将变量从ROM搬运到RAM之后,将会调用__rt_entry() 函数,该函数首先建立C语言的运行环境,包括:建立C语言运行所需要的堆栈;初始化库函数;如果使用C++还会调用其顶层构建器。

创建C语言的运行环境之后,__rt_entry() 函数会调用用户的main() 函数,当程序执行完main() 之后,会重新跳转回__rt_entry() 函数。

那么main()函数又是如何和上面的2个函数关联在一起的呢?

这是由编译器负责的。编译器将用户的main() 函数视为一个特殊的标识符,编译器会强制将__main()__rt_entry() 这两个函数与main() 函数链接到一起。

以上就是用户的main函数运行前,ARM处理器需要执行的一些操作,可以看出主要是C语言运行环境的初始化,包括全局变量的初始化、堆栈的初始化、C语言标准库的初始化。这一系列的初始化完成之后就会调用用户的main函数,开始执行用户的代码。

上面提到了要对C语言标准库进行初始化,那么标准库需要初始化些什么呢?由下一篇文章进行简要的介绍。

在这里插入图片描述

### STM32 中 `__main` 函数的作用 在嵌入式开发环境中,尤其是基于 ARM Cortex-M 的微控制器(如 STM32),程序启动过程通常由编译器工具链自动处理。`__main` 是一个特殊的函数名称,在许多 ARM 编译器中被用来表示程序的入口点[^1]。 #### 启动流程概述 当 STM32 微控制器上电或复位时,硬件会跳转到存储在向量表中的初始地址执行代码。这个初始地址指向的是启动文件(startup 文件)中的重定位代码部分。随后,控制权会被传递给 C 运行库初始化代码,即 `__main` 函数所在的位置。此阶段的主要功能包括: - **栈指针初始化**:设置 MSP 或 PSP 寄存器以定义堆栈区域。 - **数据段拷贝**:将位于 Flash 中已初始化的数据复制到 SRAM 对应位置。 - **BSS 段清零**:清除未初始化全局变量所在的 BSS 区域。 - 调用用户的 `main()` 函数。 这些操作完成后,才正式进入用户编写的应用逻辑。 #### 使用方法与注意事项 尽管开发者不需要手动实现 `__main`,了解其工作原理有助于调试复杂项目或者定制化固件行为。如果需要自定义启动序列,则可以修改链接脚本以及 startup.s 汇编源码来绕过默认提供的运行期环境准备步骤。 下面展示了一个简单的例子说明如何通过调整 linker script 和 assembly file 来掌控整个 process: ```c // main.c - 用户主程序 #include <stdint.h> void SystemInit(void); // 可选系统配置函数声明 int main() { uint32_t counter = 0; while (true){ // 主循环体 ++counter; } } ``` ```assembly /* startup_stm32f4xx.s */ .syntax unified .cpu cortex-m4 .fpu softvfp .global Reset_Handler .type Reset_Handler, %function Reset_Handler: ldr sp, =_estack /* 设置栈顶 */ bl SystemInit /* 初始化外设可选项 */ bl main /* 开始应用程序 */ loop_forever: b loop_forever /* 死循环防止退出 */ .size Reset_Handler, .-Reset_Handler ``` 注意以上仅为简化版示范用途,请依据具体 MCU 型号选用合适的模板并参照官方文档完成实际部署。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值