cancel
Showing results for 
Search instead for 
Did you mean: 

How to jump to application from bootloader in STM32H563

Hueiyi
Associate II

I referred to this article: “Bootloader jump to Application HardFault - STM32H563.”
I am also using the STM32H563, and used the following function to jump to the application, but the jump does not succeed. My test program is very simple. After creating an STM32H563 project, I only configured the UART to print messages so I can identify which program is currently running.

/* Bootloader */
typedef void (*pFunction)(void);
void relocate_exe(uint32_t app_addr)
{
    uint32_t appStack;
    uint32_t appResetHandler;
    pFunction appEntry;

    appStack = *(volatile uint32_t *)app_addr;

    appResetHandler = *(volatile uint32_t *)(app_addr + 4);
    appEntry = (pFunction) appResetHandler;

    __disable_irq();
    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;
    SCB->VTOR = (uint32_t) app_addr;
    __set_MSP(appStack);
    //__enable_irq();

    appEntry();
}

int main(void)
{
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USART3_UART_Init();
	
	char msg[128];
	sprintf(msg, "Bootloader!!!(%x)\r\n", SCB->VTOR);
	HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
	
	relocate_exe(0x8020000);   // Jump to application
	while (1);
}

 

/* Application */
int main(void)
{
  HAL_Init();
  SystemClock_Config();

  __enable_irq();
  SCB->VTOR = (uint32_t) 0x8020000;

  MX_GPIO_Init();
  MX_USART3_UART_Init();

  char msg[128];
  sprintf(msg, "Application!!!(%x)\r\n", SCB->VTOR);
  HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);

  while (1);
}

 

I also modified the STM32H563ZITX_FLASH.ld linker script accordingly.

/* Bootloader */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 640K
  FLASH    (rx)    : ORIGIN = 0x08000000,   LENGTH = 128K
}
/* Application */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 640K
  FLASH    (rx)    : ORIGIN = 0x08020000,   LENGTH = 128K
}

 

Hueiyi_2-1770701377800.png

Hueiyi_1-1770701358780.png

 

Below is the console output for reference.

Hueiyi_3-1770701651749.png

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
gbm
Principal

The subject comes back every week, so please read few dozens of past posts.

First, you should jump to the app or the bootloader before initializing ANYTHING in main(). There are many good reasons for that.

Second, the code invoking the app will usually fail if compiled with no optimization.

See this file for more details (cone and the comments):

https://github.com/gbm-ii/STM32_Inc/blob/main/cm_boot.h

 

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

View solution in original post

3 REPLIES 3
gbm
Principal

The subject comes back every week, so please read few dozens of past posts.

First, you should jump to the app or the bootloader before initializing ANYTHING in main(). There are many good reasons for that.

Second, the code invoking the app will usually fail if compiled with no optimization.

See this file for more details (cone and the comments):

https://github.com/gbm-ii/STM32_Inc/blob/main/cm_boot.h

 

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Hueiyi
Associate II

Hi gbm,
Thank you for your help—it really did solve my problem. Since this code was able to jump successfully on the STM32F103, I couldn’t figure out where the issue was coming from.

There are indeed many articles about this topic, and I should have searched more carefully. I truly appreciate your help. Thanks again!

jumman_JHINGA
Senior III

There is no need to set VTOR address again in the application code

 


/* Bootloader */
typedef void (*pFunction)(void);
void relocate_exe(uint32_t app_addr)
{
    uint32_t appStack;
    uint32_t appResetHandler;
    pFunction appEntry;

    appStack = *(volatile uint32_t *)app_addr;

    appResetHandler = *(volatile uint32_t *)(app_addr + 4);
    appEntry = (pFunction) appResetHandler;

    __disable_irq();
    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;
    SCB->VTOR = (uint32_t) app_addr;
    __set_MSP(appStack);
    //__enable_irq();

    appEntry();
}

before disable_irq .. denationalize every things using HAL_RCC_DeInit();
HAL_DeInit();