我目前正在开发针对STM32F030C8的引导加载程序固件应用程序。我在分散文件中指定了引导加载程序应用程序将占用主内存位置0x08000000至0x08002FFF(扇区0至扇区2)。我还写了一个主要的固件应用程序,存储在0x08003000到0x0800C800之间。将两个固件都下载到MCU内部闪存后,我使用以下代码从引导加载程序启动了主应用程序:
/************************************************************//**
* \brief Start the main application if available and correct
*****************************************************************/
void INTFLASH_execute_main_app(const char mode)
{
MyFunc_ptr AppEntry;
uint32_t temp[1];
IRQn_Type index;
memcpy(temp, (void*)&NVIC->ISER, sizeof(NVIC->ISER)); //Save enabled interrupts
for( index = (IRQn_Type)0; index<= (IRQn_Type)28; index++) //Disable all interrupts
NVIC_DisableIRQ(index);
AppEntry = (MyFunc_ptr) INTFLASH_calculate_page_addr(IAP_APP_START_PAGE);
if( mode || intflash_check_main_app() )
{
Main_App_ptr = (uint8_t*)AppEntry;
if( (*Main_App_ptr != 0xFF) && (Main_App_ptr) )
{
AppEntry();
}
}
memcpy( (void*)&NVIC->ISER, temp, sizeof(NVIC->ISER) ); //Restore interrupts
}
由于某种原因,当它执行AppEntry()时,它将跳转到以下代码,并且不会在位置0x08003000处执行主应用程序:
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
我以前在ARM7 MCU上使用过这种逻辑,并且运行良好,我无法弄清楚为什么它不能在基于Cortex M0的MCU上运行。任何帮助将不胜感激。
请参阅下面的Bootloader和主应用程序的分散文件:
LR_IROM1 0x08000000 0x00003000 { ; load region size_region
ER_IROM1 0x08000000 0x00003000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00002000 { ; RW data
.ANY (+RW +ZI)
}
}
LR_IROM1 0x08003000 0x0000C800 { ; load region size_region
ER_IROM1 0x08003000 0x0000C800 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00002000 { ; RW data
.ANY (+RW +ZI)
}
}
最佳答案
您必须跳转到“应用程序地址+ 4”,因为应用程序的基地址保留了初始堆栈指针的位置。因此,跳转到该地址意味着跳转到堆栈基址。
在应用程序地址+ 4下(由于32位体系结构,因此为+ 4B)是复位处理程序过程的地址。