Trouble Jumping to Bootloader from Application on STM32H747 with Riverdi Display and TouchGFX
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-17 8:04 AM
Hello everyone,
I'm facing an issue with jumping from my application to the bootloader on an STM32H747 microcontroller. I'm using a 7-inch Riverdi display and have developed graphical interfaces using TouchGFX. My application, which I've built using only the M7 core (disabling the M4 core) and FreeRTOS for task management and graphics, has its main file structured as man1.c attached.I've also created a bootloader program with the following structure: The bootloader works perfectly when the STM32H747xx_FLASH.ld file contains the following instruction:
Assolutamente! Ecco la traduzione del tuo post in inglese, adatta per un forum tecnico come quello di STM:
Subject: Trouble Jumping to Bootloader from Application on STM32H747 with Riverdi Display and TouchGFX
Hello everyone,
I'm facing an issue with jumping from my application to the bootloader on an STM32H747 microcontroller. I'm using a 7-inch Riverdi display and have developed graphical interfaces using TouchGFX. My application, which I've built using only the M7 core (disabling the M4 core) and FreeRTOS for task management and graphics, has its main file structured as follows:
I've also created a bootloader program with the following structure:
The bootloader works perfectly when the STM32H747xx_FLASH.ld file contains the following instruction:
MEMORY
{
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
/*FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K*/ /* Memory is divided. Actual start is 0x08000000 and actual length is 2048K */
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 250K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
SDRAM (xrw) : ORIGIN = 0xD0000000, LENGTH = 4M
SDRAM2 (xrw) : ORIGIN = 0xD0400000, LENGTH = 4M
}
However, when I try to jump to the bootloader from my application using a jump_to_bootloader() function, the jump to the bootloader fails. This is code snipet:
I've made to the .ld files of both the application and the bootloader.
// Application .ld
/* Memories definition */
MEMORY
{
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
/*FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K*/ /* Memory is divided. Actual start is 0x08000000 and actual length is 2048K */
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 724K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 64M
SDRAM (xrw) : ORIGIN = 0xD0000000, LENGTH = 4M
SDRAM2 (xrw) : ORIGIN = 0xD0400000, LENGTH = 4M
}
// Bootloader.ld
/* Memories definition */
MEMORY
{
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
/*FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K*/ /* Memory is divided. Actual start is 0x08000000 and actual length is 2048K */
FLASH (rx) : ORIGIN = 0x08B500000, LENGTH = 250K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
SDRAM (xrw) : ORIGIN = 0xD0000000, LENGTH = 4M
SDRAM2 (xrw) : ORIGIN = 0xD0400000, LENGTH = 4M
}
Could someone please advise on what modifications I need to make in both the application and the bootloader code to successfully jump to the bootloader? Is there something I'm missing in the process?How may I had to manage all peripherals?
Thank you in advance for your help!
Solved! Go to Solution.
- Labels:
-
TouchGFX
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-06-05 5:51 AM
Hi everyone!
After a lot of trial and error, I finally solved my STM32 dual-application setup issue. I created two projects:
A bootloader, which starts at address 0x08000000
An application, located at 0x08020000
they have these .ld files
Bootloader .ld (128KB at start of Flash):
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
}
and .ld file for the second project.
MEMORY
{
FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 896K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
QUADSPI (r) : ORIGIN = 0x90000000, LENGTH = 64M
SDRAM (xrw) : ORIGIN = 0xD0000000, LENGTH = 4M
SDRAM2 (xrw) : ORIGIN = 0xD0400000, LENGTH = 4M
}
In the main.c file of bootloader I use this function
typedef void (*pFunction)(void);
static void JumpToApplication(void)
{
__disable_irq(); // Disable all interrupts
HAL_RCC_DeInit(); // Reset clock configuration
HAL_DeInit(); // Deinit peripherals
SysTick->CTRL = 0; // Disable SysTick if running
__set_MSP(*(__IO uint32_t*)0x08020000); // Set new MSP from app vector table
SCB->VTOR = 0x08020000; // Point VTOR to new app
uint32_t JumpAddr = *(__IO uint32_t*)(0x08020000 + 4); // Reset_Handler address
pFunction Jump = (pFunction)JumpAddr;
__enable_irq(); // Re-enable interrupts if needed
Jump(); // Execute the jump
NVIC_SystemReset(); // If jump fails, reset
}
Everything now works perfectly. The bootloader initializes, then jumps to the second application at 0x0802000 without issues.
Big thanks to everyone who offered support and tips during this process — your help made it happen!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-17 8:18 AM - edited ‎2025-05-17 8:44 AM
#define BOOT_ADDR 0x080B50000
FLASH (rx) : ORIGIN = 0x08B500000, LENGTH = 250K
Should be 0x080B5000, Memory in range 0x08000000..0x081FFFFF (2MB)
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-17 8:20 AM
Are you sure ? FLASH (rx) : ORIGIN = 0x08B500000, LENGTH = 250K
too your main dont show where and how you try jump. Primary jump to system bootloader is safe from safe state of MCU optimaly after boot main with som marker. No inside RTOS No with 20 peripherals active ... NEVER.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-21 12:45 AM
Hi @MM..1 ,
Do you mean that jump from bootloader app to main application is simpler than viceversa?
Thank you again
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-26 3:20 AM
Hi everyone,
I'm currently doing some experiments with an STM32H7 dual-core setup (Cortex-M7 + Cortex-M4), where the main application runs on the M7 core with FreeRTOS.
I've attached two key files:
The main application (app_file.c.txt), which receives a CAN message and is supposed to jump to the bootloader.
The bootloader, (bootfile_c.txt) which is responsible for programming via QSPI and Flash, and is expected to send an initial CAN message upon startup.
The jump from the application to the bootloader seems to occur correctly (without a reset), but the bootloader doesn't send the first CAN message, even though this behavior is defined in its code. I suspect this might be due to the fact that I'm not performing a full system reset before jumping.
I’m also unsure if I missed modifying some required files for proper bootloader support:
system_stm32h7xx_dualcore_boot_cm4_cm7.c
startup_stm32h757xihx.s
STM32H757XIHX_RAM.ld
Should I be doing a full NVIC_SystemReset instead of just jumping?
Any guidance or examples would be greatly appreciated. Thanks in advance!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-26 5:01 AM
Hello @Sasa1234 ,
So beside changing your address which contained 9 characters instead of 8, what else did you change?
Right now, how do you know that the jump worked?
How do you know that the bootloarder doesn't send the CAN message?
Can you put breakpoint or other debugging means to figure out what is being executed correctly and what is blocking?
Regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-26 5:29 AM
Hi @GGODA ,
Honestly I am not sure about jump action but I see that, after my bootloader CAN message, display turns off and I observed an absorbed current equal 0.0 A.However If I analyze my attached code, there is a QSPI Erase that is not performed and this state ST Link can't connect to microcontroler.
Thank you again for your reply!!!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-26 7:52 AM
It's inadvisable to jump via a Callback under Interrupt Context.
This causes a problem because the NVIC state doesn't get unwound.
>>Should I be doing a full NVIC_SystemReset instead of just jumping?
That's probably a better/cleaner approach, and that you provide an expedited path from the loader's Reset_Handler entry point to the application's Reset_Handler. ie a magic value causing a near immediate control transfer.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-28 2:10 AM
Hi everyone,
I tried implementing the solution previously suggested to start the bootloader from the application using the jump_to_bootloader() function, but unfortunately, it's not working as expected.
In the file bootfile.c (attached as bootfile.c.txt), there is a function that should periodically send a CAN message as soon as the system enters the bootloader. However, I don’t see any messages being sent, and I suspect the microcontroller might be going into a hard fault right after the jump.
I’m wondering:
Is the sequence inside jump_to_bootloader() correct? Am I missing something (e.g., disabling interrupts, resetting the stack pointer, etc.)?
Could the issue be related to the .ld linker script files used in the two projects? Even though the bootloader works correctly when started directly from reset.
Has anyone encountered a similar issue or could help me figure out what to check first?
Thanks in advance for any advice or suggestions!
Any help is very much appreciated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-05-28 8:09 AM - edited ‎2025-05-28 8:11 AM
Right place isnt after HAL init but before. Optimal and this is too for jump to app
int main(void)
{
/* USER CODE BEGIN 1 */
if (*BOOT_FLAG_ADDR == BOOT_FLAG_VALUE)
{
// Cancella il flag per evitare salti infiniti
*BOOT_FLAG_ADDR = 0;
// Salta all'app secondaria
jump_to_bootloader();
}
/* USER CODE END 1 */
but primary , if you use own bootloader then after reset is normal way start bootloader = for jump to boot required is only reset...
