【STM32芯片启动流程】——结合具体启动文件和hex文件分析

一、前言

最近想把MCU相关的知识梳理一遍,希望加深自己对相关知识的理解,同时也作为备忘录提醒自己。首先是STM32的启动过程,理解这个过程是学习IAP和OTA功能以及深入stm32内核的基础。

二、总体流程介绍

1. 由boot引脚(boot0,boot1)选择启动模式;

2. 给SP、PC指针赋值;

3. 进入复位中断程序;

4. 进入main函数。

三、各个过程深入分析

1. 由boot引脚选择启动模式

stm32复位(上电复位、硬件复位、软件复位),会将复位后的起始地址和中断向量表重映射到其他地址,具体映射到哪个地址由boot0和boot1决定。具体映射关系如下图所示。

启动模式对应映射地址

其中最常用的启动模式就是映射到内部FLASH启动,这也是接下来重点介绍的模式。

映射到内部SRAM启动的使用场景比较少,代码在SRAM的执行速度较快,可运用在一些调试需频繁更新代码的场合。

映射到系统存储器一般是用于bootloader引导程序升级时使用,在程序本地升级和OTA升级时都会用。

2. 给SP、PC指针赋值

选择内部FLASH启动后,程序会将栈指针SP指向0x08000000,这个地址保存的是__initial_sp的地址,也就是程序栈顶地址,还会将程序计数器指针指向0x08000004,这个地址保存的是Reset_Handler的地址,这里结合具体的启动文件,map文件和hex文件来证实这一点。

启动文件的中断向量表
map文件和hex文件对比

这里从map文件中选取__initial_sp和Reset_Handler的地址与hex文件中最开始执行的指令比较,发现两者相等,即证明了程序的执行确实如上所述。这里有两个需要注意的点,stm32是小端模式,因此hex文件中的指令是按照字节的高位在地址高位,字节的低位在地址低位的规则。Reset_Handler的地址最后一位为啥是1,stm32的指令不都是16位和32位的嘛,其实这里涉及到指令集的问题,ARM cortexM3执行的是Thumb-2指令集,同时兼容16位的ARM指令和32位的Thumb的指令,为了区分两个指令集,规定指令最低位为1就是Thumb指令,为0就是ARM指令。

初始化SP、PC指针的示意图

3. 进入复位中断程序

上一步中PC指针指向了Reset_Handler函数,这也是程序复位后执行的第一条指令。

Reset_Handler函数内容

可以看到在Reset_Handler函数里主要执行了 SystemInit 和 __main 这两个函数,其中SystemInit函数是库函数,它的主要作用是初始化系统时钟(通过调用SetSysClock)。

__main 函数是标准的C库函数,当编译器发现了主程序中有main函数,就会自动创建__main函数。它的主要作用是初始化RW段和ZI段(通过调用__scatterload),初始化堆栈以及跳转到主程序的main函数(通过调用__rt_entry)。

4. 进入main函数

执行main函数中的while死循环,当中断到来时从中断向量表中找到对应的中断服务函数并执行。

四、结语

如有错误,欢迎评论区指正。

  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值