STM32学习笔记-启动过程

 启动模式:

M3/M4内核复位后,做的第一件事:

1、从地址0X00000000处取出堆栈指针MSP的初始值,该值就是栈顶地址;即把第一个地址处保存的值作为栈顶地址赋值为MSP;

2、从地址0X00000004处取出程序计数器指针PC的初始值,该值是复位向量;即把第二个地址处(32位单片机,第二个地址就是04)保存的数据作为中断向量表的复位向量(Reset_Handler)赋值给程序计数器指针PC;

芯片厂商可以把0X00000000和0X00000004地址映射到其他地址来决定从存储器哪个位置启动,从而引申出如下几种启动方式;

启动模式选择引脚:BOOT0和BOOT1,通过对引脚电平的控制可以实现STM32从系统存储器,主闪存FLASH或者内置SRAM启动;在系统复位后的第四个时钟上升沿采样锁存判定;

三种启动方式的差异需要先了解STM32F10X系统内存结构,如下:

0X00000000~0X07FFFFFF:boot选择区域,程式都是从0地址开始执行,通过BOOT设置映射到相应位置执行程式;

0X08000000~0X0801FFFF:主闪存区域,内置FLASH位置;BOOT配置为0X时程序跳转到这个位置开始启动;这个部分就是我们用户自己编写程序通过STLINK下载保存的地方;

0X1FFFF000~0X1FFFF7FF:系统存储器区域;BOOT配置为10时程序跳转到这个位置开始启动;这个部分是STM32出厂就带有的BOOTLOADER程序,用于串口下载的引导程序,用户可以通过串口下载程序,通过BOOTLOADER引导后将程序同样保存到主闪存内;所以执行系统存储器启动,就是执行串口下载,将程序下载到FLASH里;一般理解为串口下载程序的办法,当程序下载完成后,BOOT引脚还是要变更成主闪存启动,因为程序已经保存到FLASH里;系统存储器并不是启动程序的一种方式,而是下载程序的一种方式,程序还是保存在FLASH里,需要从FLASH启动程序才能使STM32正常运行;

0X1FFFF800~0X1FFFF88F:选项字节,存放一些独立于用户代码的配置参数,STM32出厂已设定;不会因为掉电或者用户下载程序而丢失;

0X20000000~0X3FFFFFFF:SRAM区域,BOOT配置为11时程序跳转到这个位置启动;一般为程序员调试程序用途,在不擦除FLASH的情况下,修改部分代码内容后调试;掉电丢失;

0X40000000~0X40023400:外设寄存器地址,也是存储器的一部分,操作这个寄存器就可以操作对应外设;

0XE0000000~0XE0100000:M3/4内核的外设寄存器地址;

启动流程:

第一步:RESET复位

第二步:从0X00000000位置开始启动程序,由于BOOT配置,可映射到其他启动位置;按正常flash启动方式来说,则映射到0X00000000获取MSP值(栈顶地址),和0X00000004获取PC值(指向Reset_Handler,在STM32的启动文件中);

第三步:调用用户自己编写的main函数;

启动文件说明:

1、初始化MSP;

2、初始化PC;

3、设置堆栈大小,Heap_Size(堆)、Stack_Size(栈)

4、初始化中断向量表;__Vectors定义

DCD     __initial_sp               ; Top of Stack就是在获取栈顶指针MSP

5、调用初始化函数;可选的,如调用Systeminit函数;

6、调用__main函数,标准C库函数,执行一系列设置;

7、调用用户自己编写的main函数;

Reset_Handler函数说明

汇编语言:
Reset_Handler    PROC
     EXPORT  Reset_Handler         [WEAK]  //标明Reset_Handler函数是全局属性,可被外部调用
     IMPORT  __main    //申明要调用来自外部的__main函数 
     IMPORT  SystemInit   //申明要调用来自外部的SystemInit函数 
     LDR     R0, =SystemInit   //将SystemInit函数的地址写到R0寄存器
     BLX     R0     

/*BLX reg是跳转到由寄存器reg给出的地址,并根据REG的LSB切换处理器;状态还要把转移前的下条指令地址保存到LR。这行代码就是实现调用SystemInit函数运行,运行之后跳到下一条指令执行*/
     LDR     R0, =__main    //同上
     BX      R0                        //同上
     ENDP

/*EXPORT:标明全局属性,可被外部使用*/

/*IMPORT:申明来自外部文件,类extern*/

/*PROC:定义子程序*/

/*ENDP:表示子程序结束*/

/*WEAK:弱定义,表示用户可以在其他地方重新定义这个函数,此时这里的这个函数失效*/

栈(Stack):

编译器自动分配和释放,存放函数参数、局部变量等;函数变量多,嵌套关系复杂时就要加大栈

堆(Heap):

程序员分配和释放,如malloc、calloc、realloc等

流程图解:实际指针地址可能因为工程文件大小不同会有差异,主要说明启动过程的执行方案;

参考:

1、全是干货 | STM32启动过程及启动模式详解【非常重要】_哔哩哔哩_bilibili

2、STM32启动方式及内存分析_哔哩哔哩_bilibili

3、STM32上电之后的工作流程,stm32汇编初步及启动代码分析_哔哩哔哩_bilibili

  • 32
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值