Skip to main content
Yves Bmnt
Associate III
October 17, 2024
Solved

Bootloader jump to app not working on STM32G491

Hi all,

I am trying to launch the app from a bootloader code that I copied from a project on an STM32L0 and STM32F446, it worked fine there but somehow my app doesn't start on the STM32G491.

Here's the code for the jump:

 

 

static void bootloader_jump_to_app(void)
{
 uint32_t JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4u);

 pFunction Jump = (pFunction)JumpAddress;


 if (!bootloader_check_integrity())
 {
 bootloader_send_message("Abort\r", 8u);
 bootloader_init();
 }
 else
 {
		bootloader_send_message("Starting\r", 9u);

		HAL_FLASH_Lock(); // lock flash after memory erase + write

		HAL_RCC_DeInit();
		HAL_DeInit();

		SysTick->CTRL = 0u;
		SysTick->LOAD = 0u;
		SysTick->VAL = 0u;

		SCB->VTOR = (__IO uint32_t)APP_ADDRESS;

		__set_MSP(*(__IO uint32_t*)APP_ADDRESS);

		Jump();
		while(1);
 }
}

 

 

I have modified my .ld file accordingly with app start address 0x08003000, I compared the memory part with the app to the bin file and it's similar, I don't understand where the problem comes from, even though I noticed some differences in the APIs between STM32L0 and G4 series, all the code examples seem to match, or maybe I missed something, can anybody help please?

This topic has been closed for replies.
Karl Yamashita
Karl YamashitaBest answer
Principal
October 18, 2024

Did you makes changes to the system_stm32g4xx.c file for the application?

if not,

  • Uncomment #define USER_VECT_TAB_ADDRESS
  • change VECT_TAB_OFFSET 0x00000000U to the application address
If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source

20 replies

ST Technical Moderator
October 17, 2024

Hello @Yves Bmnt ,

Please have a look at this article How to jump to system bootloader from application ... - STMicroelectronics Community. This will help you to jump to system bootloader from application code.

 
 
In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
Yves Bmnt
Yves BmntAuthor
Associate III
October 17, 2024

thank you for your quick answer.

After reading the article, I modified my code to this, but the app doesn't run somehow. Also, I don't understand why my original code works with STM32L010 & STM32F446 but not with STM32G491.

 

 

static void bootloader_jump_to_app(void)
{
 uint32_t JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4u), i= 0u;

 pFunction Jump = (pFunction)JumpAddress;


 if (!bootloader_check_integrity())
 {
 bootloader_send_message("Abort\r", 8u);
 bootloader_init();
 }
 else
 {
		bootloader_send_message("Starting\r", 9u);

		HAL_FLASH_Lock(); // lock flash after memory erase + write

		/* Disable all interrupts */
		__disable_irq();

		HAL_RCC_DeInit();
		//HAL_DeInit();

		SysTick->CTRL = 0u;
		//SysTick->LOAD = 0u;
		//SysTick->VAL = 0u;

		/* Clear Interrupt Enable Register & Interrupt Pending Register */
		for (i=0;i<5;i++)
		{
			NVIC->ICER[i]=0xFFFFFFFF;
			NVIC->ICPR[i]=0xFFFFFFFF;
		}

		/* Re-enable all interrupts */
		__enable_irq();

		//SCB->VTOR = (__IO uint32_t)APP_ADDRESS;

		__set_MSP(*(__IO uint32_t*)APP_ADDRESS);

		Jump();
		while(1);
 }
}

 

 

gbm
Super User
October 17, 2024

Check the assembly code generated for the above routine (your project .list file). If there is any instruction using sp register between the MSM setting code and jumping to application, it will fail. If this is the case - use -O2 optimization level, which should solve the problem. Also, leave the VTOR setting statement uncommented.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
ST Technical Moderator
October 17, 2024

Noted in the AN2606:

"On devices with dual bank boot, to jump to system memory from user code the user must first remap the system memory bootloader at address 0x00000000 using SYSCFG register (except for STM32F7 series), then jump to bootloader..."

So to jump, try adding this line in your code just before jumping:

SYSCFG->MEMRMP = 0x01;

Hope this helps ! Please, let me know about your progress on this issue.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
Yves Bmnt
Yves BmntAuthor
Associate III
October 17, 2024

I placed this line right before the Jump(); but it didn't work :(

MM..1
Super User
October 17, 2024

Primary test start app from stlink change to your hex and address

"C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exe" -c port=SWD mode=UR -d ledtest.hex -v -g 0x08004000

 

ST Technical Moderator
October 17, 2024

Did you try to alter the linker script for the application and change the Flash origin?

As you see in AN4767 that when FB_MODE is set, the addresses are remapped:

ImenD_0-1729189135301.png

 

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
Yves Bmnt
Yves BmntAuthor
Associate III
October 18, 2024

sure, I use 0x08003000 as Flash origin:

/* Memories definition */
MEMORY
{
 RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
 FLASH (rx) : ORIGIN = 0x8003000, LENGTH = 244K
}

 

FShah.1
Associate III
December 2, 2024

Hi,

I will appreciate your prompt response. I found the issue in my code, and now the CRC is working correctly.

However, another problem has arisen. As you know, I am working on a bootloader program. My application code is successfully transferred from the source to the controller via the serial port. But when the code attempts to set the reset handler and jump to the application code, it is failing.

I am using the STM32F446 microcontroller.

First, I copied the code to memory address 0x08040000. Then, bootloader copied to the application memory address, which is 0x08020000. The CRC of the application on the host side, the CRC at address 0x08040000, and the CRC at address 0x08020000 are all the same.

I checked the memory locations, and they have the same data. However, the jump_to_application function is not successful.

Blink LED Application: I changed the Flash address in linker file

/* Memories definition */

MEMORY

{

RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K

FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 128K

}

 

/*!< Uncomment the following line if you need to relocate the vector table

anywhere in Flash or Sram, else the vector table is kept at the automatic

remap of boot address selected */

#define USER_VECT_TAB_ADDRESS

 

#if defined(USER_VECT_TAB_ADDRESS)

/*!< Uncomment the following line if you need to relocate your vector Table

in Sram else user remap will be done in Flash. */

/* #define VECT_TAB_SRAM */

#if defined(VECT_TAB_SRAM)

#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.

This value must be a multiple of 0x200. */

#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.

This value must be a multiple of 0x200. */

#else

#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.

This value must be a multiple of 0x200. */

#define VECT_TAB_OFFSET 0x00020000U /*!< Vector Table base offset field.

This value must be a multiple of 0x200. */

#endif /* VECT_TAB_SRAM */

#endif /* USER_VECT_TAB_ADDRESS */

 

 

Bootloader: jump_to_application function:

static void goto_application(void)
{
 
printf("Gonna Jump to Application\r\n");
 
 
 
// Set the Vector Table Offset Register (VTOR) to the address of the application
SCB->VTOR = ETX_APP_FLASH_ADDR;
// Get the application reset handler address
void (*app_reset_handler)(void) = (void*)(*((volatile uint32_t*) (ETX_APP_FLASH_ADDR + 4U)));//Application starting address
// Optionally turn off the LED
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
 
/* Reset the Clock */
HAL_RCC_DeInit();
HAL_DeInit();
__set_MSP(*(volatile uint32_t*) ETX_APP_FLASH_ADDR);
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
 
/* Jump to application */
app_reset_handler();    //call the app reset handler
}
Kindly advise on how to solve this problem. I am very close to the finish line, but something I am doing seems to be wrong! Please help. Thank you
 
gbm
Super User
December 2, 2024

See my remark in this thread, below the main article:

https://community.st.com/t5/stm32-mcus/how-to-share-an-api-between-a-bootloader-and-an-application/ta-p/736681

- check the code generated by the compiler, maybe change optimization level.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
FShah.1
Associate III
December 2, 2024

I appreciate your response.

I checked the memory regions where the code is being written and identified an issue with how the data was being written to the flash memory—specifically, little-endian / big-endian issue. After addressing this, the application is now successfully loading and working.

Thanks for being responsive. I will reach out to you for assistance with other parts of the bootloader process during my development.

Thanks again,
FS