Reputation: 21
Im using a custom board based on STM32F4 with 2MB internal flash.
uint32_t nAppAdr=0x08020000;
bool bootloader_jump_to_user_app(uint32_t nAppAdr)
{
bool ret = true;
void(*app_reset_handler)();
//shut down any tasks remaining
HAL_RCC_DeInit();// to turn off the PLL and set the clock to it's default state
HAL_DeInit();// to disable all the peripherals
SysTick->CTRL = 0;//to turn off the systick
SysTick->LOAD = 0;
SysTick->VAL = 0;
//disable interrupts
__set_PRIMASK(1);
__disable_irq();.
SCB->VTOR = nAppAdr;//change this
//configure the MSP by reading the value from the base address
uint32_t msp_value = *(__IO uint32_t*) nAppAdr;
__set_MSP(msp_value);
uint32_t resethandler_address = *(__IO uint32_t*) (nAppAdr + 4);
//app_reset_handler = (void*)resethandler_address;
app_reset_handler = (void (*)(void)) (*((uint32_t*)(resethandler_address)));
//jump to reset handler of the user app.
app_reset_handler();
return ret;
}
#define USER_VECT_TAB_ADDRESS
#define VECT_TAB_OFFSET 0x00020000
this should make my user application bootloadable.
When the custom bootloader is executed, the last statement of function bootloader_jump_to_user_app, specifically the call to app_reset_handler(), causes an exception of type : "HardFault exception. The processor has escalated a configurable-priority exception to HardFault. A bus fault has occurred on an instruction prefetch (CFSR.IBUSERR,BFAR). Exception occurred at PC=0x1478048, LR=0x8000f85 "
this is supposed to be simple. Anything I'm missing? why I get the exception? any help is appreciated thanks
Upvotes: 0
Views: 3900
Reputation: 7594
I believe the problem is in this line:
app_reset_handler = (void (*)(void)) (*((uint32_t*)(resethandler_address)));
resethandler_address
already contains the address, but you are taking the value at the address and thus jumping "into the unknown". It should just be:
app_reset_handler = (void (*)(void)) (resethandler_address);
Update: I think some of the things you do are not necessary, but I am not sure which (if any) may cause problems. I normally do something like this:
...
<peripheral de-init>
...
__disable_irq(); // Note: remember to enable IRQ in application
__DSB();
__ISB();
uint32_t mainStackPointer = *(volatile uint32_t *)(nAppAdr);
__set_MSP(mainStackPointer);
uint32_t programResetHandlerAddress = *(volatile uint32_t *) (nAppAdr + 4);
void (* programResetHandler)(void) = (void (*)(void)) programResetHandlerAddress;
programResetHandler();
You do not mention how you burn the Application to the flash. Are you sure it is located at the correct address?
In the linker script file (STM32F4?????_FLASH.ld
if you are using STM32CubeIDE) of the Application, you need to define the FLASH as starting at 0x08020000: In the MEMORY
section, change the line for FLASH
to something like this (LENGTH
depends on the specific area allocated to the application):
FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 5*128K /* Sector 5-9 */
Upvotes: 1