STM32启动过程

 参考资料

1.https://blog.csdn.net/weixin_42328389/article/details/120656722

2.https://space.bilibili.com/678329477/channel/seriesdetail?sid=427350

3.https://blog.csdn.net/CynalFly/article/details/114757347

4.https://blog.csdn.net/qq_39400113/article/details/116051401

5.https://blog.csdn.net/tianshi_1988/article/details/51084516

 本文主要回答关于STM32是如何运行的,为什么是main函数的疑问。

启动文件:告诉MCU如何找到并执行main函数,STM32F4的启动文件为《startup_stm32f407xx.s》

启动文件完成的主要工作:

  1.设置堆栈指针SP = _initial_sp

  2.设置PC指针 = Reset_Handler

  3.配置系统时钟

  4.配置外部SRAM用于程序变量等数据存储(可选)

  5.调用C库中的_main函数,最终调用main函数

上述知识点见《Cortex M3与M4权威指南》的4.8 Reset and reset sequence

 

 

 

 

STM32的启动方式:

BOOT0引脚状态 BOOT1引脚状态 启动模式 使用情景
0 X 从Flash中启动 正常运行时选择这种模式
1 0 从系统存储器启动 做ISP下载时用
1 1 从内嵌SRAM中启动 调试用,一般很少使用

 

存储器映射(memory map):把整个MCU内以外的存储器、外设等所有模块全部进行统一的编址,即使用地址来描述各个模块的位置。

STM32是32位单片机,地址总线是32位的,故可以寻址的空间大小为2^32B=4GB。

《Cortex M3与M4权威指南》中,预先定义好的存储器映射(半导体厂家大范围定义),ST在该基础上所做的存储器定义

上电后,CPU从地址0开始执行

存储器重映射:解决 从地址0开始执行程序三种启动方式下程序存放地址不同的问题

从Flash中启动时,芯片上电后,0x0800 0000地址被映射到0地址处

从系统存储器启动时,芯片上电后,0x1FFF 0000地址被映射到0地址处。开始执行厂家提供的BootLoader,将程序下载到系统的Flash中。

  注意:程序下载好后,要重新设定BOOT引脚电平,让程序从Flash中启动

从内嵌SRAM中启动时,芯片上电后,0x2000 0000地址被映射到0地址处

STM32属于小端模式:较高的有效字节存储在较高的存储器地址,较低的有效字节存储在较低的存储器地址。

中断向量表位于代码段的最前面,其内存放中断服务程序的入口地址。

借用硬汉的图,

 

 

 上图解释:1.启动方式为从Flash中启动,上电后从0x8000 0000地址开始读取内容(此时还未开始执行程序);

      2.开始四个字节是堆栈栈顶指针的地址,0x2000 26B0(小端模式),MSP寄存器的值为0x2000 26B0

      3.后四个字节的内容(0x0800019D)装入程序计数器PC中.

      4.CPU从PC寄存器指向的物理地址取出第一条指令开始执行。也就是开始执行复位中断服务程序Reset_Handler。

        跳转到了另外的地址上开始执行程序,避开了中断向量表中的下一个中断

        触发中断时,是从中断向量表中获取对应中断函数的入口地址,转到对应的地址执行,我们所编写的是中断服务函数中的内容

 

 

      5. 调用__mian函数,__main函数是由编译器自动创建的,无法找到。当编译器发现定义了main函数,那么就会自动创建__main。可以用在线调试的方式来查看。

        __main函数最后会跳转到main函数

      6.回到熟悉的main函数。

  

突然想到的问题:如何判断当前CPU是大端的,还是小端的?

  方法1:使用联合体 union

  方法2:强制类型转换

 

posted @ 2023-02-11 22:05  涧落水寒  阅读(191)  评论(0)    收藏  举报