Hi everyone,
I’m working on a custom bootloader for an STM32H750 and need some help. My goal is to be able to update the unit from USB and for doing so I use an external eeprom to store the MCU FW and load it into RAM at startup. The main reason to use the RAM to execute the code is that the h750 flash is 128KB and it can only be erased by 128KB sector. I can succesfully write the code into the eeprom and load into ram at startup (address 0x20000000). However, when I try to jump to it, the debugger shows a 0x2xxxxxxx address but it get stuck.
For the application code, I took the original flash based code, modified the scatter file for the linker as follows:
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x20000000 0x00020000 { ; load region size_region ER_IROM1 0x20000000 0x00020000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } RW_IRAM2 0x24020000 0x00080000 { ; RW data .ANY (+RW +ZI) } }
I also tried setting the VTOR to 0x20000000 in the application, but it didn’t help. Looking at the .bin file, the stack pointer (SP) and program counter (PC) appear to point to valid addresses within the 0x20000000 range.Here is the part of the code which is supposed to jump to the app.
#define APP_BASE_RAM (0x20000000) uint32_t *p; void (*jmp)(); ---------- ..... __disable_irq(); p = (uint32_t *)(APP_BASE_RAM); SCB->VTOR = (uint32_t)p; // Set Vector Table Offset Register (VTOR) to RAM base __set_MSP(*p); __DSB(); // Data Synchronization Barrier __ISB(); // Instruction Synchronization Barrier jmp = (void (*)())p[1]; __enable_irq(); while (true) ;
I’m not sure if there’s something I’m missing in the application code or bootloader setup. Has anyone encountered a similar issue or have suggestions on what I could check next?
Thanks in advance!
Milorad Cvjetkovichere is the correct code: SysTick->CTRL = 0; NVIC->ICER[0] = 0xffffffff; NVIC->ICER[1] = 0xffffffff; NVIC->ICER[2] = 0xffffffff; NVIC->ICER[3] = 0xffffffff; NVIC->ICER[4] = 0xffffffff; NVIC->ICER[5] = 0xffffffff; NVIC->ICER[6] = 0xffffffff; NVIC->ICER[7] = 0xffffffff;
p = (U32 *)(APP_BASE_RAM);
SCB->VTOR = (uint32_t)p; // Set Vector Table Offset Register (VTOR) to RAM base // this doesnt change anything if removed__set_MSP(*p);
jmp = (void (*)())p[1]; jmp();while (true) ;
There are 2 possibilities, either content at 0x20000000 and 0x20000004 is not what you expect, or jmp value after jmp = (void (*)())p[1]; is not what you expect.You should be able to single step through that code and see exactly what goes wrong.
jmp
jmp = (void (*)())p[1];