2025-08-27 11:55 PM - last edited on 2025-08-28 3:16 AM by Andrew Neil
Hello,
I am working on an STM32F746 project where I have implemented a bootloader.
The setup is as follows:
Application image is stored in external QSPI flash.
Bootloader copies the image from QSPI to SDRAM (IS42S32400F at 0xC0000000).
After copying, I set SCB->VTOR = 0xC0000000 and jump to the application Reset_Handler.
The copy is verified: I have cross-checked the SDRAM contents with the QSPI image, and the data is copied correctly.
I also created a test application that only sets a GPIO pin high (no SystemInit(), no HAL_Init(), no HAL_RCC_DeInit()).
Even in this simple case, after the bootloader jumps to the reset handler, I get this error:
Break at address "0x242" with no debug information available, or outside of program code.
The Reset_Handler address from the SDRAM vector table is correct (e.g., 0xC00002B5), and VTOR is updated to 0xC0000000.
But execution always ends up breaking at 0x242.
Has anyone faced this issue when trying to execute code from SDRAM after copying from QSPI?
Any hints on what I might be missing (cache setup, MPU, remap, or SDRAM execution settings)?
Thanks in advance.
2025-08-28 12:54 AM
Hello,
First test to do is to disable the cache.
2025-08-28 1:11 AM - last edited on 2025-08-28 1:15 AM by mƎALLEm
Kindly review my jump function .
thank you
void VerifyAndJumpOrDump(uint32_t app_size)
{
uint32_t v0 = *(volatile uint32_t*)(APP_BASE + 0);
uint32_t v1 = *(volatile uint32_t*)(APP_BASE + 4);
SCB->VTOR = APP_BASE;
print_hex("VTOR (should be APP_BASE) ", SCB->VTOR);
print_hex("Vector[0] (SP) at APP_BASE ", v0);
print_hex("Vector[1] (PC) at APP_BASE ", v1);
if (!is_valid_sp(v0)) {
printf("Invalid SP at APP_BASE! scanning SDRAM for vector table...\r\n");
int32_t found_offset = scan_for_vector_table(0x10000); // scan first 64KB
if (found_offset >= 0) {
printf("Found candidate vector at APP_BASE + 0x%X\r\n", found_offset);
dump_memory_hex(APP_BASE + found_offset, 8);
} else {
printf("No plausible vector found in first 64KB of SDRAM.\r\n");
}
// Dump first 16 words at APP_BASE to help debug
dump_memory_hex(APP_BASE, 16);
while (1) { HAL_Delay(1000); } // halt for debug
}
// SP looks valid, check PC
if (!is_valid_pc(v1)) {
printf("PC looks invalid (not in flash or SDRAM). Dumping memory near APP_BASE...\r\n");
dump_memory_hex(APP_BASE, 32);
while (1) { HAL_Delay(1000); } // halt for debug
}
// ensure Thumb bit in PC
if ((v1 & 0x1U) == 0) {
printf("PC LSB (Thumb bit) is NOT set! Forcing Thumb bit for jump, but image may be wrong.\r\n");
}
// Optional: configure MPU so SDRAM is executable (call only if using MPU)
// MPU_Config_SDRAM_Executable();
// Clean D-cache for the app area (aligned to 32 bytes)
uint32_t start = APP_BASE & ~0x1FU;
uint32_t end = (APP_BASE + app_size + 31) & ~0x1FU;
uint32_t size = end - start;
printf("Cleaning D-Cache for 0x%08X - 0x%08X (size 0x%X)\r\n", start, end, size);
// SCB_CleanInvalidateDCache_by_Addr((uint32_t*)start, size);
// SCB_InvalidateICache();
__DSB(); __ISB();
// Disable interrupts, stop SysTick, clear pending/enable bits
__disable_irq();
SysTick->CTRL = 0;
for (int i = 0; i < 8; i++) {
NVIC->ICPR[i] = 0xFFFFFFFF;
NVIC->ICER[i] = 0xFFFFFFFF;
}
// Set VTOR (redundant if already set but safe)
SCB->VTOR = APP_BASE;
__DSB(); __ISB();
// Set MSP then jump
__set_MSP(v0);
__DSB(); __ISB();
pFunction Jump = (pFunction)(v1 | 0x1U); // ensure Thumb bit set
printf("Jumping to 0x%08X (Thumb)\r\n", (unsigned)(v1 & ~1U));
Jump();
// should not return
while (1);
}
2025-08-28 1:13 AM - edited 2025-08-28 1:14 AM
If your solution is not solved why did you accept the solution?
In next time please use </> button to insert your code. Please read this post.
I'm editing your post then.
2025-08-28 2:01 AM
I am really sorry kindly continue this topic
2025-08-28 4:42 AM - edited 2025-08-28 4:51 AM
Did you try to disable the cache or not?
The closest example I can find (it's for H7) is the Template example ExtMem_Boot:
It can execute the code from SDRAM after copying the binary from an external memory (QSPI for example).