2026-02-07 8:32 AM
Board: STM32H750B-DK (MB1381-H750XB-B01, Product ID DK32H750B$AT1)
Tools: STM32CubeIDE, STM32CubeMX (FW_H7 V1.12.1), STM32CubeProgrammer.
Goal: Configure and debug an application to run from external QSPI flash at 0x90000000.
Board: STM32H750B-DK (MB1381-H750XB-B01, Product ID DK32H750B$AT1)
Tools: STM32CubeIDE, STM32CubeMX (FW_H7 V1.12.1), STM32CubeProgrammer.
Goal: Configure and debug an application to run from external QSPI flash at 0x90000000.
A. CubeMX & Project Configuration
Created project via Board Selector (not MCU selector).
Verified QUADSPI configured in Memory-Mapped mode (Clock Prescaler=2, CS High Time=2, Flash Size=26).
Programming & External Loader
STM32CubeProgrammer: Successfully programmed my .hex file to 0x90000000 (log confirms full erase, download, and verify).
External Loader: MT25TL01G_STM32H750B-DISCO.stldr is selected with both Enabled and Initialize checked in the IDE debug configuration.
C. Debugging Attempts & Failures
Default debug launch always halted at 0x80011b0 (internal flash), ignoring external flash.
Attempt 1 (VTOR): Added SCB->VTOR = 0x90000000; early in main() and also tried setting it via GDB Run Commands (set *((unsigned int *)0xE000ED08) = 0x90000000).
Result: The debugger seemed to jump but immediately hit a HardFault or Lockup state. The processor appears to crash as soon as it tries to fetch instructions from external flash.
Attempt 2 (Run from CubeProgrammer): Used CubeProgrammer's "Run after programming" feature. The board enters a locked state (no functional code execution, debugger reports "ARM M in lockup state").
The board is now unresponsive in normal operation. The core seems to be in a lockup, likely because it is trying to boot from/branch to an uninitialized or incorrectly accessed QSPI memory region.
My specific questions for the community are:
Recovery: What is the most reliable way to recover from this lockup on the STM32H750B-DK? I understand I may need to force boot from internal memory, but the board lacks a standard BOOT0 jumper. Should I bridge a specific resistor pad (e.g., R100)? Or is a full chip erase via STM32CubeProgrammer under reset sufficient?
Root Cause: Given that the flash programs and verifies correctly, what step am I missing to ensure the QSPI is initialized for memory-mapped mode before the CPU attempts to execute from 0x90000000? Does the SystemInit() function need modification for this board?
Configuration: Has anyone successfully automated this process with this specific board? What is the correct sequence in CubeMX/IDE to ensure the application is built and debugged for external flash from the start?