2026-02-11 2:10 AM
Board: STM32H750B-DK Discovery Kit
STM32CubeIDE: Version 2.0.0 (Build 26820_20251114_1348 UTC)
STM32Cube FW_H7: v1.12.1
STM32CubeMX: v6.16.0
TouchGFX Designer: v4.26.0 (MVP pattern)
External Memory: 1GB QSPI Flash (MT25TL01G) + 8MB SDRAM
Created TouchGFX project in Designer, saved and generated code
Opened .ioc file in STM32CubeMX v6.16.0
Configured:
QSPI in memory-mapped mode with 30-bit addressing (1GB flash)
SDRAM via FMC
MPU configured with QSPI region execution enabled (0x90000000, 256MB)
Vector table relocated to 0x90000000
Linker script modified for external flash execution
Debugger fails with protocol error when attempting to debug:
Error in final launch sequence:
Failed to execute MI command: monitor reset halt
Protocol error with Rcmd
Failed to execute MI command: monitor mww 0xE000ED08 0x90000000
Protocol error with Rcmd
Failed to execute MI command: monitor reg pc 0x90000004
Protocol error with Rcmd:white_heavy_check_mark: Code programs successfully to QSPI at 0x90000000 using STM32CubeProgrammer (.bin file)
:white_heavy_check_mark: After programming and power cycle, board runs code correctly (verified with LED patterns)
:white_heavy_check_mark: LED patterns show:
Early QSPI initialization succeeds
SDRAM initialization succeeds
Full QSPI init succeeds
TouchGFX initialization succeeds
Main loop execution confirmed
:white_heavy_check_mark: Programming works; standalone execution works
:cross_mark: Debug fails every time with protocol error
:cross_mark: Error occurs during reset/halt sequence before code executes
:cross_mark: Debugger cannot access QSPI memory region (0x90000000) at reset time
:cross_mark: Trying to attach to running target fails
Tried all reset modes: Software system reset, Hardware reset, Core reset, System reset
Unchecked "Run to main()"
Added reset delay (500ms, 1000ms)
Removed all initialization commands (just monitor reset halt)
Tried with empty initialization commands
Modified ST-LINK speed (4000kHz → 1000kHz)
Added early QSPI initialization in main() before any HAL init
Minimal QSPI config: clock enable, reset, CR=0x00000101, DCR=0x001E0000, CCR=0x00000100
LED debugging confirms early QSPI init runs when code executes normally
MPU region 1 configured with execution enabled at 0x90000000
Programmed .elf, .hex, .bin files
Starting address 0x90000000 for .bin
Verified with STM32CubeProgrammer
Unchecked "Run after programming"
Power cycle after programming
BOOT0 pin verified LOW (boot from flash)
Power cycled after each programming attempt
ST-LINK firmware updated
Different USB ports/cables tested
static void Early_QSPI_Init(void)
{
__HAL_RCC_QSPI_CLK_ENABLE();
RCC->AHB3RSTR |= RCC_AHB3RSTR_QSPIRST;
for(volatile int i=0;i<100;i++);
RCC->AHB3RSTR &= ~RCC_AHB3RSTR_QSPIRST;
QUADSPI->CR = 0x00000101;
QUADSPI->DCR = 0x001E0000;
QUADSPI->CCR = 0x00000100;
}// Region 1: QSPI Flash (0x90000000, 256MB) - Executable
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;MEMORY
{
FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 256M
RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
/* ... */
}How to make the debugger initialize QSPI before attempting to set vector table?
Is there a way to execute initialization scripts before the debugger tries to access 0x90000000?
Can we redirect the debugger to use internal flash vectors while keeping code in QSPI?
Is there a known issue with OpenOCD and STM32H7 QSPI memory-mapped mode during debug?
Does the debugger need special configuration for memory-mapped QSPI?
What is the recommended debug workflow for STM32H7 with code executing from external QSPI?
Boot from internal flash with loader that copies/initializes QSPI?
Two-stage bootloader approach?
Debug from internal flash first, then move to QSPI?
Has anyone successfully debugged STM32H750B-DK with TouchGFX and code in external QSPI?
What specific debugger settings are required?
Any special OpenOCD scripts or cfg files?
Could this be related to the ST-LINK firmware or STM32CubeIDE version?
Using IDE 2.0.0 (2025) with FW_H7 1.12.1 - any compatibility issues?
Alternative approach: Is it possible to keep the vector table in internal flash but execute code from QSPI?
SCB->VTOR = 0x08000000 while code executes from 0x90000000?
Flash with CubeProgrammer
Power cycle
Cannot debug - forced to rely on LED indicators and printf over serial
Any guidance, working debug configurations, or alternative approaches would be greatly appreciated!
*Will provide any additional files or configuration details needed.*
Solved! Go to Solution.
2026-02-11 1:21 PM - edited 2026-02-12 8:34 AM
You need to compile and upload the Boot example to the MCU internal Flash.
The TouchGFX application seems to be located in the QSPI Flash at the address 0x90000000, and the TouchGFX assets at 0x90200000 and this is based on the generated linker file by TouchGFX designer:
FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 2048K
ASSETS_FLASH (r) : ORIGIN = 0x90200000, LENGTH = 126M
BOOTLOADER (xrw) : ORIGIN = 0x08000000, LENGTH = 128k
Then upload your TouchGFX application, it will be located at the QSPI flash. No need to configure QSPI flash from your side it is already configured by ExtMem_Boot application.
Hope that helps.
2026-02-11 2:16 AM
Hello,
What are you trying to do? execute from QSPI (XIP mode)?
I'm not sure if that initialization is sufficient:
static void Early_QSPI_Init(void)
{
__HAL_RCC_QSPI_CLK_ENABLE();
RCC->AHB3RSTR |= RCC_AHB3RSTR_QSPIRST;
for(volatile int i=0;i<100;i++);
RCC->AHB3RSTR &= ~RCC_AHB3RSTR_QSPIRST;
QUADSPI->CR = 0x00000101;
QUADSPI->DCR = 0x001E0000;
QUADSPI->CCR = 0x00000100;
}
Try to use the HAL and inspire from the External memory boot template provided in the HAL package:
2026-02-11 2:19 AM
Not sure if this will help, but when You can programm the External Flash via CubeProgrammer, You have a working external loader for your flash. You have to tell the CubeIDE to use this Loader by selecting it in the Debug Configuration::
2026-02-11 2:21 AM - edited 2026-02-11 2:21 AM
Another question, why are you configuring QSPI and other stuff while you can start your project from TouchGFX Designer based on TBS board (STM32H750B-DK board) that it will configure all the stuff for you including the QSPI interface?
2026-02-11 9:48 AM
Thank you, this is exactly how I started TouchGFX Designer -> generate code -> open files -> STM32CubeIDE Folder -> open ioc -> configure the rcc, set the rtc timer, and adjust the clock source ->save -> generate code -> open IDE -> build -> debug -> Fail
2026-02-11 1:21 PM - edited 2026-02-12 8:34 AM
You need to compile and upload the Boot example to the MCU internal Flash.
The TouchGFX application seems to be located in the QSPI Flash at the address 0x90000000, and the TouchGFX assets at 0x90200000 and this is based on the generated linker file by TouchGFX designer:
FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 2048K
ASSETS_FLASH (r) : ORIGIN = 0x90200000, LENGTH = 126M
BOOTLOADER (xrw) : ORIGIN = 0x08000000, LENGTH = 128k
Then upload your TouchGFX application, it will be located at the QSPI flash. No need to configure QSPI flash from your side it is already configured by ExtMem_Boot application.
Hope that helps.