STM32 Bootloader程序中Jump2App函数分析

Jump2App函数代码

#define     __IO    volatile                  /*!< defines 'read / write' permissions   */
#define ApplicationAddress    0x8003000
pFunction Jump_To_Application;
uint32_t JumpAddress;
typedef  void (*pFunction)(void);

/**
 * @brief  Set the Main Stack Pointer
 *
 * @param  topOfMainStack  Main Stack Pointer
 *
 * Assign the value mainStackPointer to the MSP 
 * (main stack pointer) Cortex processor register
 */
__ASM void __set_MSP(uint32_t mainStackPointer)
{
  msr msp, r0
  bx lr
}
void Jump2App(void)
{
	/* Test if user code is programmed starting from address "ApplicationAddress" */
    if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
    { 
      /* Jump to user application */
      JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
      Jump_To_Application = (pFunction) JumpAddress;
      /* Initialize user application's Stack Pointer */
      __set_MSP(*(__IO uint32_t*) ApplicationAddress);
      Jump_To_Application();
    }
}

用户代码的堆栈地址的判断

if ((((__IO uint32_t)ApplicationAddress) & 0x2FFE0000 ) ==
0x20000000)
{
……
}

其中ApplicationAddress是0x8003000是用户程序Flash的首地址,首地址里面存放的是用户代码的堆栈地址,((__IO uint32_t)ApplicationAddress)这个就是讲用户代码的堆栈地址取出来,堆栈地址指向RAM,而RAM的起始地址是0x20000000,所以(…… & 0x2FFE0000 ) )这个是判断用户代码的堆栈地址是否落在0x20000000~0x2001ffff之间。

启动设置

JumpAddress = (__IO uint32_t) (ApplicationAddress + 4);

STM32 Bootloader程序中Jump2App函数分析_第1张图片

从中断向量表中可以看到,程序代码偏移4个字节是复位地址,所以JumpAddress获取的是复位地址。

Jump_To_Application = (pFunction) JumpAddress;

后面这句则是将复位地址转换成函数指针。

__set_MSP((__IO uint32_t) ApplicationAddress);

这个是把用户代码的栈顶地址设为栈顶指针

Jump_To_Application();

这个是设置PC指针为复位地址。

CORTEX-M3上电后后检测BOOT引脚的电平来决定PC的位置。例:BOOT设置为FLASH启动,启动后CPU会先取两个地址:一个是栈顶地址,另一个是复位地址。

你可能感兴趣的:(嵌入式C)