分析--STM32启动流程

STM32启动实现流程:

①设置堆栈指针SP = __initial_sp
​
②设置PC指针 PC= Reset_Header
​
③配置系统时钟
​
④配置外部SRAM用于程序变量等数据存储
​
⑤调用源库中的_main函数,最终调用main函数

STM32上电或者复位后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存,硬件复位后,CPU内地时序逻辑电路首先完成两个工作:以主闪存存储器(Main Flash)启动为例,首先将0x08000000位置存放的堆栈栈顶地址存放在SP中(MSP),然后将0x08000004(32位)位置存放的向量地址装入PC程序计数器,CPU通过在PC寄存器指向的物理地址取出第一条指令开始指向程序,执行Reset_Handler。 

STM32的三种启动模式

分析--STM32启动流程_第1张图片

  • 主闪存存储器启动,将主Flash地址0x08000000映射到0x00000000,启动之后就相当于从0x08000000开始。主闪存存储器是STM32内置的Flash,通常使用JTAG或者SWD模式下载程序时,就是下载到这个里面。

  • 系统存储器启动。复位后,从系统存储器地址0x1FFF F000开始执行代码。系统存储器是芯片内部一块特定的区域,芯片出厂预置Bootloader,就是通常说的ISP程序,是一个ROM区。

  • 内置SRAM启动,将SRAM地址0x20000000映射到0x00000000,内置SRAM,这个模式一般用于程序调试。

STM32启动代码详解:( startup_stm32f40_41xxx.s )

1、开辟栈(stack)空间,用于局部变量,函数调用,函数参数等;

EQU是宏定义伪指令,类似于#define,AREA开辟一段数据空间,段名STACK,NOINIT不初始化,确定权限可读可写,ALIFN = 3 表示按照2的三次方byte对齐(八字节对齐)SP mod 8 = 0,SPACE Stack_Size 汇编操作,给STACK段分配0x00000400字节的连续内存空间,__initial_sp标号栈顶。

2、申请堆(heap)空间,主要用于动态内存分配,如malloc,calloc,realloc等函数内存分配的变量空间在应用在堆内。

分析--STM32启动流程_第2张图片

分配一段连续的内存空间,命名为HEAP段,堆大小为0x00000200,其中heap_base为堆的开始地址,heap_limit为堆的结束地址。

3、PRESERVE8指定当前文件保持堆栈八字节对齐,THUMB指示后面的指令都是THUMB指令集,Cortex-M4处理器只支持在Thumb状态下执行指令。EXPORT语句声明外部可引用(弱定义),主要提供给连接可文件或其他应用文件。

分析--STM32启动流程_第3张图片

 4、建立中断向量表,中断向量表定位在代码段的最前面,具体的物理地址由连接器的配置参数(keil --IROM1)决定,DCD表示申请分配一个四字节内存空间,每个中断向量占用四个字节地址。

 ( 中间部分省略..... )

分析--STM32启动流程_第4张图片

    __Vectors_Size                           0x00000188   Number         0  startup_stm32f40_41xxx.o ABSOLUTE
    __Vectors                                0x08000000   Data           4  startup_stm32f40_41xxx.o(RESET)
    __Vectors_End                            0x08000188   Data           0  startup_stm32f40_41xxx.o(RESET)

Vectors_Size 申请内存空间,通过在.map的记录刚好匹配。

5、复位中断服务程序,调用源库中的_main函数,最终调用main函数

分析--STM32启动流程_第5张图片

 WEAK声明其他的同名标号优先于该标号被引用,若外部已经声明,则外部声明优先。IMPORT伪指令用于通知编译器要使用的标号在其他源文件中定义,供外部调用.

你可能感兴趣的:(嵌入式基础,单片机,stm32,c语言)