TouchGFX Application Shows Black Screen After Bootloader Jump
Hello everyone,
I am working on a custom bootloader for an STM32H743-based TouchGFX project and facing a very strange issue specifically with the TouchGFX application after jumping from bootloader.
STM32H743 Bootloader Successfully Jumps to Simple App but TouchGFX Application Shows Black Screen After Bootloader Jump.
I would appreciate any guidance from people who have experience with STM32H7 + TouchGFX + bootloader integration.
Hardware / Project Details
MCU:
- STM32H743IIT6
Frameworks:
- STM32CubeIDE
- TouchGFX
- FreeRTOS
Peripherals Used in TouchGFX App:
- FMC SDRAM
- LTDC
- DMA2D
- QSPI
- I2C
- TIM2
External Memories:
- SDRAM framebuffer at 0xD0000000
- QSPI assets at 0x90000000
Bootloader Functionality
The bootloader:
- Initializes USB Host + FATFS
- Detects pendrive
- Reads image.bin and extflash.bin
- Programs internal flash and external QSPI successfully
- Uses APPLICATION_ADDRESS = 0x08040000
- After flashing, bootloader jumps to application
Important:
- Simple LED blinking application works correctly through the same jump function
- Only TouchGFX application fails
Symptoms
- TouchGFX application works perfectly when flashed using STM32CubeProgrammer directly.
- But after bootloader flashing + jump:
- Display stays completely black
- No GUI appears
- No LED toggles inside main()
- HardFault / MemFault / BusFault handlers are NOT entered
- Application seems to die before reaching main()
- If same binary is programmed manually via CubeProgrammer:
- GUI works correctly even after reset
This strongly suggests:
- The binary itself is valid
- Flashing process mostly works
- Problem happens specifically during bootloader jump/startup
Application Linker Configuration
Application FLASH origin:
FLASH (rx) :
ORIGIN = 0x08040000
Vector table offset in system_stm32h7xx.c:
#define USER_VECT_TAB_ADDRESS
#define VECT_TAB_OFFSET 0x00040000U
Framebuffer sections:
BufferSection (NOLOAD) > SDRAM
BitmapCacheSection (NOLOAD) > SDRAM1
ExtFlashSection > QSPI
Stack pointer at application start:
- 0x24000000 region (AXI SRAM)
Current Jump Function
Current jump code:
typedef void (*pFunction)(void);
void Jump_To_User_Application(void)
{
uint32_t appStack;
uint32_t appEntry;
appStack = *(__IO uint32_t*)APPLICATION_ADDRESS;
appEntry = *(__IO uint32_t*)(APPLICATION_ADDRESS + 4);
if (((appStack & 0xFF000000) == 0x24000000) ||
((appStack & 0xFF000000) == 0x20000000))
{
__disable_irq();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
for (uint32_t i = 0; i < 8; i++)
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
HAL_MPU_Disable();
SCB_DisableICache();
SCB_DisableDCache();
__DSB();
__ISB();
SCB->VTOR = APPLICATION_ADDRESS;
__set_MSP(appStack);
pFunction JumpToApp;
JumpToApp = (pFunction)(appEntry);
JumpToApp();
}
}Debugging Already Done
- Verified linker FLASH origin = 0x08040000
- Verified VECT_TAB_OFFSET = 0x00040000U
- Verified application vector table exists at 0x08040000
- Verified MSP points to 0x24000000 region
- Verified TouchGFX binary works when flashed manually
- Added LED toggles between all init calls in main()
- Added HardFault / BusFault / MemFault handlers with LED blinking
- Application never reaches main() after bootloader jump
- Fault handlers are also never reached
- Simple non-TouchGFX LED application works correctly with same jump function
Main Question
Why would:
- Simple application jump correctly
- But TouchGFX application fail before entering main()
even though:
- linker script is correct
- vector table offset is correct
- binary works through CubeProgrammer
- flash contents appear correct
Could this be related to:
- AXI SRAM stack pointer
- cache state
- MPU state
- SDRAM/FMC state
- incorrect binary flashing alignment
- Thumb bit/reset vector issue
- startup code incompatibility after bootloader jump
Has anyone successfully implemented STM32H7 bootloader + TouchGFX application jump reliably?
Any suggestions would be greatly appreciated.
Thank you.