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);
从中断向量表中可以看到,程序代码偏移4个字节是复位地址,所以JumpAddress获取的是复位地址。
Jump_To_Application = (pFunction) JumpAddress;
后面这句则是将复位地址转换成函数指针。
__set_MSP((__IO uint32_t) ApplicationAddress);
这个是把用户代码的栈顶地址设为栈顶指针
Jump_To_Application();
这个是设置PC指针为复位地址。
CORTEX-M3上电后后检测BOOT引脚的电平来决定PC的位置。例:BOOT设置为FLASH启动,启动后CPU会先取两个地址:一个是栈顶地址,另一个是复位地址。