当前位置:   article > 正文

【Cortex-M内核篇】--自复位_sysresetreq

sysresetreq

[Cortex-M内核系列]–复位

复位类型

  • 上电复位。复位微控制器中的所有部分,其中包括处理器、调试支持部件和外设等.
  • 系统复位。只会复位处理器和外设,不包括处理器的调试支持部件。
  • 处理器复位。只复位处理器

上电复位我们都知道,那要如何执行系统复位和处理器复位?
可以通过控制SCB的AIRCR寄存器的SYSRESETREQ(系统复位)和VECTREST(处理器复位)来控制

在这里插入图片描述

SYSRESETREQ(系统复位)

其实可以直接使用CMSIS提供的接口NVIC_SystemReset

在这里插入图片描述

VECTREST(处理器复位)

在这里插入图片描述

复位流程(3个步骤)

  • 步骤一:PC指针指向0x00000000(映射到了0x08000000,由boot引脚决定启动方式),获取栈顶指针给MSP

  • 步骤二:PC指针指向0x00000004,获取复位向量表,并跳转到复位向量中执行

  • 步骤三:执行SystemInit(系统时钟初始化),并跳转到main入口执行用户程序

在这里插入图片描述

使用KEIL进行调试,点击RST执行复位,MSP也获取到了栈顶指针地址,PC获取到了复位向量地址,开始执行复位向量函数

在这里插入图片描述

KEIL调试验证

复位向量中主要是调用SystemInit,并跳转到main入口函数

启动文件中的复位向量代码
; Reset handler
Reset_Handler   PROC
                EXPORT  Reset_Handler   [WEAK]  ;可被外部调用和改写
                IMPORT  __main                  ;引入外部函数(main函数入口)
                IMPORT  SystemInit              ;引入系统初始化(系统时钟、外设)
                LDR     R0, =SystemInit         ;保存SystemInit函数地址到R0寄存器
                BLX     R0                      ;调用
                LDR     R0, =__main             ;保存main函数地址到R0寄存器
                BX      R0                      ;跳转执行
                ENDP
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

问题:这个栈顶指针怎么计算?

首先在启动文件startup_stm32f10x_hd.s中分配栈大小0x00000400

Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
  • 1
  • 2
  • 3
  • 4
  • 5

编译查看烧录的BIN文件前4个字节(0x020000450)

在这里插入图片描述

我们知道RAM地址是从0x02000000开始的,在启动文件中设置的栈大小为0x400,理论上不是应该为0x02000400,为什么会多出来0x50。

查看了一下MAP文件,可以看出来,从0x02000000开始的80个字节,存放了一些全局变量数据(.data(初始化的全局变量)和.bss段()未初始化或者初始化为0))

所以栈顶指针的位置就是从0x02000000开始偏移80(0x50)个字节后开始,在加上分配的0x400栈大小,最后的0x020000450就是栈顶地址。

在这里插入图片描述

参考文档《ARM Cortex-M3与Cortex-M4权威指南》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/713247
推荐阅读
相关标签
  

闽ICP备14008679号