一、启动模式,决定向量表的位置

     当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 进入到复位序列!