赞
踩
上电复位我们都知道,那要如何执行系统复位和处理器复位?
可以通过控制SCB的AIRCR寄存器的SYSRESETREQ(系统复位)和VECTREST(处理器复位)来控制
其实可以直接使用CMSIS提供的接口NVIC_SystemReset
步骤一:PC指针指向0x00000000(映射到了0x08000000,由boot引脚决定启动方式),获取栈顶指针给MSP
步骤二:PC指针指向0x00000004,获取复位向量表,并跳转到复位向量中执行
步骤三:执行SystemInit(系统时钟初始化),并跳转到main入口执行用户程序
使用KEIL进行调试,点击RST执行复位,MSP也获取到了栈顶指针地址,PC获取到了复位向量地址,开始执行复位向量函数
复位向量中主要是调用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
首先在启动文件startup_stm32f10x_hd.s中分配栈大小0x00000400
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
编译查看烧录的BIN文件前4个字节(0x020000450)
我们知道RAM地址是从0x02000000开始的,在启动文件中设置的栈大小为0x400,理论上不是应该为0x02000400,为什么会多出来0x50。
查看了一下MAP文件,可以看出来,从0x02000000开始的80个字节,存放了一些全局变量数据(.data(初始化的全局变量)和.bss段()未初始化或者初始化为0))
所以栈顶指针的位置就是从0x02000000开始偏移80(0x50)个字节后开始,在加上分配的0x400栈大小,最后的0x020000450就是栈顶地址。
参考文档《ARM Cortex-M3与Cortex-M4权威指南》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。