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伪指令用于通知编译器要使用的标号在其他源文件中定义,供外部调用.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。