微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

分析--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的三种启动模式

  • 主闪存存储器启动,将主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 举报,一经查实,本站将立刻删除。

相关推荐