1.平台
GD32E230C8
2.问题解决前的代码
/* 程序跳转函数 */
typedef void (*Jump_Fun)(void);
void IAP_ExecuteApp (uint32_t App_Addr)
{
Jump_Fun JumpToApp;
if ( ( ( * ( __IO uint32_t * ) App_Addr ) & 0x2FFE0000 ) == 0x20000000 ) //检查栈顶地址是否合法.
{
JumpToApp = (Jump_Fun)*( __IO uint32_t *)(App_Addr + 4); //用户代码区第二个字为程序开始地址(复位地址)
// MSR_MSP( * ( __IO uint32_t * ) App_Addr ); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
__set_MSP(*(__IO uint32_t *)App_Addr);
JumpToApp(); //跳转到APP.
}
else{
// printf("> Illegal top stack address!\r\n");
}
}
3.问题解决后的代码
/* 程序跳转函数 */
typedef void (*Jump_Fun)(void);
Jump_Fun JumpToApp;
void IAP_ExecuteApp (uint32_t App_Addr)
{
if ( ( ( * ( __IO uint32_t * ) App_Addr ) & 0x2FFE0000 ) == 0x20000000 ) //检查栈顶地址是否合法.
{
JumpToApp = (Jump_Fun)*( __IO uint32_t *)(App_Addr + 4); //用户代码区第二个字为程序开始地址(复位地址)
// MSR_MSP( * ( __IO uint32_t * ) App_Addr ); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
__set_MSP(*(__IO uint32_t *)App_Addr);
JumpToApp(); //跳转到APP.
}
else{
// printf("> Illegal top stack address!\r\n");
}
}
4.总结
两段代码唯一的区别就是将JumpToApp这个函数指针的定义从局部变量变为了全局变量。改动的契机是仿真时断点到JumpToApp()位置,查看JumpToApp的值是0xFFFFFFFF:
然后就想将JumpToApp定义为全局变量,再仿真看看JumpToApp的值的变化情况。结果这回再看JumpToApp的值正常了,程序也不跑进HardFault_Handler里了,App工程的代码也能仿真、正常运行了。
这个问题自己尝试解决了一天的时间,应该是编译器的锅,代码逻辑之外的问题还是挺不好找的。