YounesCHTIOUI
YounesCHTIOUI

Reputation: 21

STM32F4: jump from custom bootloader to user application triggers a HardFault exception

Im using a custom board based on STM32F4 with 2MB internal flash.

  1. I have a small custom minimal bootloader application (that goes to sector 0 located at 0x08000000 in internal flash) my user application is stored in sector 5 located in 0x08020000 in internal flash. So my bootloader does not flash any user application in internal flash of the MCU. It does only jump to user application. the custom bootloader jumps to the application using the call to this function:bootloader_jump_to_user_app :

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;

}

  1. In my user application, in file system_stm32f4xx.c, I define USER_VECT_TAB_ADDRESS, and set VECT_TAB_OFFSET to 0x08020000 (location in internal flash of my user application

#define USER_VECT_TAB_ADDRESS

#define VECT_TAB_OFFSET 0x00020000

this should make my user application bootloadable.

  1. I burn my user application in internal flash in sector 5 (Starting address 0x08020000. I checked this step (compare the first bytes in this location with the first few bytes of the bin file).

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

Answers (1)

nielsen
nielsen

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

Related Questions