一、启动模式,决定向量表的位置
当CPU上电后,首先代码区(Flash)应该从地址为0x00000000开始,而数据区(SRAM)应该从0x20000000开始,Cortex - M3 CPU总是通过代码区获得复位向量。STM32F10XXX微处理器中运用了特殊的机制使得STM32不仅可以通过Flash(主闪存和系统闪存)启动,同时还可以从SRAM中启动。
STM32 有下面3种启动方式:
关于Main Flash/System Memory/SRAM 可以参见下面内存映射:
从上图可以看出 0x00000000 - 0x08000000 之间这128M空间是预留的,该区称为Boot Memory Space(Aliased to Flash or systen memory depending on BOOT pins)。
(1)从Main Flash 启动:Boot Space 是Main Flash 的别名。以0x08000000 对应的内存为例,则该块内存既可以通过0x00000000 操作也可以通过0x08000000 操作,且都是操作的同一块内存
(2)从System Memory启动:Boot Space 是System Memory的别名。以0x1FFFFFF0对应的内存为例,则该块内存既可以通过0x00000000 操作也可以通过0x1FFFFFF0操作,且都是操作的同一块内存
(3)从SRAM 启动:SRAM 只能通过0x20000000进行操作,与上述两者不同 。从SRAM 启动时,需要在应用程序初始化代码中重新设置向量表的位置。
eg:void SystemInit (void)
{
...... #ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH.*/ #endif
}
二、向量表解析
分析STM32的启动文件startup_stm32f10x_hd.s(大容量)主要做了以下事情:
(1)设置初始堆栈指针(SP)
(2)设置初始程序计数器(PC)为复位向量,并在执行main函数前初始化系统时钟
(3)设置向量表入口为异常事件的入口地址
(4)复位之后处理器为线程模式,优先级为特权级,堆栈设置为MSP主堆栈
三、开机实际运行过程
通过仿真器仿真,发现开机后程序就直接跳转到Reset_Handler,从.map文件看Reset_Handler的地址是0x080003a5并不是0x08000000(因为此时是从Flash中启动的,故应该是0x08000000)。那么STM32是如何从0x08000000过渡到0x080003a5?
查看Cortex - M3权威指南中文版本中复位序列中相应的说明:
也就是说上电复位的时候,刚开始CPU的主动权还是掌握在CM3中。CM3执行了寄存器的初始化及取复位向量表并执行!
这个绝大多数单片机不同,传统的ARM架构总是从0地址开始执行,并且0地址是有一条跳转指令的。在CM3中0地址处存的是MSP的位置,这并不是执行指令只是一个数据表。
另外还有一个问题,如何进入到复位序列?
触发STM32进入复位序列的有以下条件:
(1)System reset
(2)Power reset
(3)Backup domain reset
刚上电时就是通过Power reset 进入到复位序列!