打印
[STM32F1]

STM32的上电启动过程

[复制链接]
1149|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jonas222|  楼主 | 2025-1-29 22:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、先说启动文件
    我们正常在操作一款单片机的时候,都是从main函数开始进行编程的,但是单片机上电是从main函数开始执行的吗?答案当然是否定的,在main函数之前单片机最先执行的是硬件设置SP、PC然后是“启动文件”,一般主要是项目文件里面的startup_xxxxx.s文件。    其实不光STM32系列单片机是这样,我们接触的NXP的微控制器、TI的MSP430以及51单片机等等其实都是有上述的启动文件的。启动文件负责的就是从单片机复位开始到main函数之前这段时间所需要进行的工作。我们一般很少接触启动文件的主要原因是开发环境往往给开发者自动的提供了这个启动文件,不需要我们再去操心,直接从main函数开始进行设计就可以了。

2、STM32三种启动方式    接触过STM32系列单片机的朋友应该知道STM32有三种启动模式,用户可以通过设置BOOT0和BOOT1的引脚电平状态,来选择复位后的启动模式。    需要注意的是STM32上电复位以后,代码区都是从0x00000000开始的,三种启动模式只是将各自存储空间的地址映射到0x00000000中。
    1)从Flash启动,将Flash地址0x08000000映射到0x00000000,这样启动以后就相当于从0x08000000开始的,这是我们最常用的模式;
    2)从SRAM启动,将SRAM地址0x20000000映射到0x00000000,这样启动以后就相当于从0x20000000开始的,用于调试,笔者基本没用过;
    3)从系统存储器启动(可以看上篇文章里的内存映射图,System memory),将系统存储器地址0x1FFFF000映射到0x00000000,这样启动以后就相当于从0x1FFFF000开始执行的,值得注意的是这个系统存储器里面存储的其实是STM32自带的Bootloader代码,这其实是一个官方的IAP,它提供了可以通过UART1接口将用户的代码下载到Flash中的功能,下载完以后再切换到从Flash中启动就可以正常运行了。打个比方这个官方的Bootloader就相当于我们玩路由器时的“不死breed”。笔者之前在调STM32低功耗的时候将下载口给复用了其他功能导致“变砖”,就是通过这种方式恢复的。
启动模式
3、切回正题
    下面我们来具体看一下从用户的Flash启动STM32,从上电到main函数之间的这段时间都做了什么。
    1)第一步是硬件设置SP、PC
    我们参考《Cortex-M3权威指南》向量表章节表7.6,如下图所示:
上电后的向量表
    前两段地址主要是用来指定SP和PC的初值,上一节我们已经知道了映射关系,所以这时已自动从0x08000000位置处读取数据赋值给了栈指针SP,从0x08000004位置处读取数据赋值给了PC。需要注意的是这个复位向量初始值并不是固定的,可以通过一个叫“向量表偏移量寄存器”来修改定位。
向量表偏移寄存器
    下图是我们那个开源OLED时钟项目的HEX文件,用J-Flash打开就可以看到设置完的SP=0x20005B88,PC=0x0800282D。
J-Flash
2)第二步是设置系统时钟    我们接着来追踪系统的运行轨迹,上面我们已经知道了PC的地址为0x0800282D,但是这没有遵循4字节对齐,我们将其对齐为0x0800282C,这时我们打开项目文件里面的.map文件,找到这个地址,如下图示:
.map文件
    我们发现来到了第一节说的startup_xxxxx.s文件,我们打开startup文件找到:
startup文件
    我们发现运行到了SystemInit,C的世界我们就不陌生了,在项目文件的system_stm32f10x.c里面可以找到SystemInit函数,也就是初始化系统时钟了。    3)第三步是___main    到这里大家可能会以为已经到了main函数了,其实不是这样的。___main和main是不一样的,我们寻找这个___main会发现找不到,startup文件里面没有,map文件里面也没有。其实它是在MDK自带的库里面了,主要的功能是软件设置SP、加载.data\.bss并初始化栈区。由于需要在线跟踪才能看到,我在这里就不给大家列出来了,感兴趣的朋友可以深入研究一下。
    4)最后来到C的世界
    在执行到___main的最后就跳转到了C文件的main函数了。    最后用一张图来整体看一下流程:
流程图

使用特权

评论回复
沙发
星辰大海不退缩| | 2025-1-30 10:31 | 只看该作者
单片机上电是从系统函数进行执行的

使用特权

评论回复
板凳
adolphcocker| | 2025-2-4 19:53 | 只看该作者
STM32单片机的上电启动过程包括确定启动模式、初始化堆栈指针和程序计数器、执行复位处理函数、配置系统时钟和外设、初始化数据段和BSS段,最后跳转到main函数

使用特权

评论回复
地板
jackcat| | 2025-2-5 10:26 | 只看该作者
初始化堆栈指针(SP)和程序计数器(PC)

使用特权

评论回复
5
tabmone| | 2025-2-5 15:58 | 只看该作者
系统运行轨迹指向SystemInit函数,该函数位于system_stm32f10x.c文件中。
SystemInit函数负责初始化系统时钟,设置系统的工作频率。

使用特权

评论回复
6
benjaminka| | 2025-2-5 16:20 | 只看该作者
如果选择了从系统存储器启动,STM32会从地址0x1FFF F000开始执行代码。系统存储器是芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,也就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。启动的程序功能由厂家设置,一般用于串口下载程序等特定用途。

使用特权

评论回复
7
alvpeg| | 2025-2-6 10:46 | 只看该作者
如果应用程序代码不在默认的0x00000000地址处,则需要在启动代码中重定位向量表到应用程序代码的起始地址。

使用特权

评论回复
8
belindagraham| | 2025-2-6 12:42 | 只看该作者
当STM32单片机上电后,硬件会自动设置堆栈指针(SP)和程序计数器(PC)。
堆栈指针通常初始化为一个预设值,而程序计数器则指向复位向量表的起始地址,通常是0x08000004。

使用特权

评论回复
9
mnynt121| | 2025-2-6 14:54 | 只看该作者
启动文件中包含一些汇编指令,用于进一步的硬件初始化工作。这些指令可能会对一些特殊的寄存器进行配置,或者执行一些与硬件相关的低级操作,以确保系统的正常运行环境被正确设置。

使用特权

评论回复
10
robincotton| | 2025-2-6 15:42 | 只看该作者
在SystemInit函数执行完毕后,系统跳转到___main函数。
___main函数主要负责软件设置SP、加载.data和.bss段并初始化栈区。
在___main函数的最后,系统跳转到用户编写的main函数,开始执行C程序。

使用特权

评论回复
11
robincotton| | 2025-2-6 17:24 | 只看该作者
STM32单片机上电或复位后,会根据BOOT0和BOOT1引脚的电平状态确定启动模式

使用特权

评论回复
12
STM32的上电启动过程,没有看到流程图

使用特权

评论回复
13
qiufengsd| | 2025-2-13 17:19 | 只看该作者
在启动文件中,会有专门的函数来配置系统时钟,比如SystemInit函数。它会对时钟源、倍频系数等进行设置,为后续的系统运行提供合适的时钟频率。不同的STM32型号和应用场景可能需要不同的时钟配置。

使用特权

评论回复
14
usysm| | 2025-2-13 18:39 | 只看该作者
系统复位后,硬件会自动对齐到0x08000144地址,执行SystemInit函数来初始化系统时钟

使用特权

评论回复
15
uiint| | 2025-2-13 19:02 | 只看该作者
STM32有三种启动模式,即从主闪存存储器启动(这是最常用的模式)、从系统存储器启动和从内置SRAM启动。启动模式的选择由BOOT0和BOOT1引脚的电平状态决定。在上电或复位时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存,以确定启动模式。

使用特权

评论回复
16
bartonalfred| | 2025-2-13 19:59 | 只看该作者
复位后,堆栈指针(SP)被设置为复位向量后的值,这通常是在系统内存的末端。

使用特权

评论回复
17
kkzz| | 2025-2-13 21:03 | 只看该作者
启动文件执行完成后,会跳转到用C语言编写的程序部分,通常是main函数所在的文件。这是用户编写的主要程序入口,程序从此开始执行用户自定义的功能。

使用特权

评论回复
18
hudi008| | 2025-2-14 09:26 | 只看该作者
在主函数中,应用程序通常会进行进一步的初始化,然后进入一个无限循环,在这个循环中处理应用程序的逻辑。

使用特权

评论回复
19
mickit| | 2025-2-14 11:46 | 只看该作者
设置中断向量表的起始地址,确保异常和中断能够正确响应。

使用特权

评论回复
20
hearstnorman323| | 2025-2-14 13:08 | 只看该作者
当STM32单片机上电后,硬件会自动设置堆栈指针(SP)和程序计数器(PC)。堆栈指针通常初始化为一个预设值,而程序计数器则指向复位向量表的起始地址,通常是0x08000004

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

1461

帖子

0

粉丝