Cortex M3 (STM32)

1.启动流程
     有两根boot pin,来选择启动设备,一般是从flash启动,当然也可以从system memory或者SRAM启动。
     如果走system memory启动的话,其实是走ST固化在这片存储区的Embedded boot loader。这其实就是一个bootloader,他能提供给我们很多其他的功能,比如IAP(In-Application Programming)
再看memory map,以STM32F103ZET6为例,主要是看block 0

0x0000 0000 ~ 0x0007 FFFF这一段,会被boot pin连接到flash(sram,system memory)上
系统上电后,系统会跑reset流程,当进入软件流程时,如下进行
在离开复位状态后,CM3做的第一件事就是读取下列两个 32位整数的值:
  •      从地址 0x0000,0000处取出 MSP的初始值。 
  •      从地址 0x0000,0004 处取出 PC 的初始值——这个值是复位向量,LSB 必须是 1。然后从这
个值所对应的地址处取指。


系统reset向量一定是要在0地址处,而异常向量表可以通过SCB_VTOR来修改。而且向量表的结构是固定的,详情请见下图
再看DMR的中断向量代码:
__root  const  APP_INTVECT_ELEM  __vector_table[] @ ".intvec" = {
    { .Ptr = (void *)__sfe( "CSTACK" )},  /*  0, SP start value. */
    __iar_program_start,                  /*  1, PC start value. */
    App_NMI_ISR,                          /*  2, NMI.            */
    App_Fault_ISR,                        /*  3, Hard Fault.     */
        ……
}

APP_INTVECT_ELEM  是一个union
typedef  union {
    CPU_FNCT_VOID   Fnct;
    void           *Ptr;
} APP_INTVECT_ELEM;

  • 第一个成员就是MSP(Main Stack Pointer)值,__sfe( "CSTACK" )指CSTACK段的下一个字节,因为Coretex M3的堆栈是向上生长的,所以这个值正好是栈底的位置。
  • 第二个成员__iar_program_start则是IAR提供的一个标准函数,其源代码并不可见,但他会调用几个函数来完成全局变量以及外部memory的初始化。其内容可参考[原创]在main()之前,IAR都做了啥? - jk的专栏 - 博客频道 - CSDN.NET