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的
三种启动模式
:
-
从
主闪存存储器
启动,将主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等函数内存分配的变量空间在应用在堆内。
分配一段连续的内存空间,命名为HEAP段,堆大小为0x00000200,其中heap_base为堆的开始地址,heap_limit为堆的结束地址。
3、PRESERVE8指定当前文件保持堆栈八字节对齐,THUMB指示后面的指令都是THUMB指令集,
Cortex-M4处理器只支持在Thumb状态下执行指令
。EXPORT语句声明外部可引用(弱定义),主要提供给连接可文件或其他应用文件。
4、
建立中断向量表
,中断向量表定位在代码段的最前面,具体的物理地址由连接器的配置参数(keil –IROM1)决定,DCD表示申请分配一个四字节内存空间,每个中断向量占用四个字节地址。
( 中间部分省略….. )
__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函数
WEAK声明其他的同名标号优先于该标号被引用,若外部已经声明,则外部声明优先。IMPORT伪指令用于通知编译器要使用的标号在其他源文件中定义,供外部调用.