你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32上电引导过程

[复制链接]
STMCU小助手 发布时间:2020-12-16 09:12
STM32上电引导过程

& W9 ?# k4 s6 J3 {0 t
01  STM32的三种启动模式
) P& \# v$ M! p, l, J
STM32有三种启动模式:FLASH启动、SRAM启动和系统存储器启动,通常三种启动方式由外部引脚boot0和boot1的电平决定。每个系列boot0和boot1电平对应的意义可能不同,下表是STM32F4xx系列的启动方式选择
, C) E6 D+ j2 L, r, {) Y! E
2.1.png

( Q4 t( i0 U9 x0 H9 h3 z, Q" F1 N5 N
当STM32上电时,无论哪种启动模式,程序都将会从地址0x0000 0000开始执行,三种启动模式只是将各自存储空间映射到地址0x00000000。事实上,原存储空间的内容仍然被保留,也就是说从地址0x0000 0000和原存储地址都可以开始访问程序。

# s: _, Y3 c: m. G4 n
1) Flash启动,将Flash地址0x0800 0000映射到0x0000 0000,这样启动以后程序相当于是从0x0800 0000开始的,这是我们最常用的模式;
1 ~' l, O% E0 T- o
2) SRAM启动,将SRAM地址0x2000 0000映射到0x00000000,这样启动以后程序相当于是从0x2000 0000开始的;

9 Q/ h& V# Z( _% e! U
3) 系统存储器启动,将系统存储器地址0x1FFFF000映射到0x0000 0000,这样启动以后就相当于从0x1FFFF000开始执行的,值得注意的是这个系统存储器里面存储的其实是STM32自带的Bootloader代码,其实是一个官方的IAP,它提供了可以通过UART1接口将用户的代码下载到Flash中的功能,下载完以后再切换到从Flash中启动就可以正常运行了。
' L1 ?5 i/ z9 A) h; Z( x
02  启动文件
7 W9 @3 C: W6 k: ^% P3 t, r
STM32同其它单片机和DSP一样,虽然是从main函数开始编程的,其实上电后并不是从main函数开始执行的,在进入main函数之前,STM32的CPU会最先设置SP(栈指针)、PC(程序计数器指针),然后执行“启动文件”,这个启动文件就是工程文件夹中的startup_stm32xxxx.s文件。
6 p, ~2 ?# ~% n1 q* Y
启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:
1、初始化堆栈指针SP=_initial_sp
2、初始化程序计数器指针PC=Reset_Handler
3、初始化中断向量表
4、配置系统时钟
5、调用C库函数__main(__main并不是main函数)初始化用户堆栈,从而最终调用main函数去到C的世界

- W! |3 ?. t6 X5 [$ y$ s9 P* _$ p' w4 H* W9 c# B9 C$ I. w. n0 M
03  上电启动流程

' J5 \( R( L7 n4 |+ Z# R4 [
我们以Flash启动模式为例。上电后,地址0x0800 0000开始的程序被映射到地址0x0000 0000,然后程序从0x0000 0000开始执行。

1 R( M; g( |- M3 u) D6 o( O
CPU会从地址0x0000 0000读取32位长度的值,并赋值给栈指针SP;然后从地址0x0000 0004读取32位长度的值复制给程序计数器指针PC,程序将会从PC指针内容处开始执行。
, r/ l" ]' Y4 z/ _/ w" Y
为了验证这一点,我们用在线仿真的方式查看地址0x0000 0000开始的数据:
* }8 \, {7 b0 r7 a- y7 F
2.2.png

: c  l% b$ o/ f% ]* n/ E
想了解启动映射过程的朋友可以在这里分别查看地址0x0000 0000和地址0x08000 0000开始的存储区域,会发现两个完全是复制粘贴的关系。
1 p! H* C+ @3 B( _* J* D
那么由上图可以看出SP=0x20000738,PC=0x08000165,也就是说程序会从地址0x08000165开始执行。
* x8 A% n2 d: v3 d3 ~# j
打开map文件(如何生成map文件,公众号iFTrue未来已来中有对应的文章讲解),查看0x08000165这个地址处放的是什么程序?

2 {5 D( y3 l! h' a( l# r
2.3.png
$ a+ \2 s1 V+ u4 l. a
可以看到这里是复位入口地址Reset_Handler,这个入口地址在前面提到的“启动文件”startup_stm32xxxx.s中会有定义。打开工程中的启动文件,找到Reset_Handler的位置:

# ^& [. m) C; T' ~& k; }9 E
2.4.png
" W, ?) b3 N! d. g) I% b, x' a
这段函数将会首先调用SystemInit函数对系统时钟进行初始化配置,这个函数可以在system_stm32fxxx.c中找到。然后会继续调用__main库函数(__main并不是main函数),主要的功能是软件设置SP、加载.data.bss并初始化栈区。
$ t7 V+ ]3 D. O# K/ a& v, r
在执行到__main函数的最后,会跳转到mian()函数,这时便来到了我们的C语言环境。
' S  K0 Q) v9 {
文章出处:  雷 I 神 iFTrue未来已来

- l$ ^" v: U8 Y; X0 J0 o2 R; G) w! V& _% L

- d: @# y1 L, F% b
赞 收藏 评论0 发布时间:2020-12-16 09:12

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版