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!
Did you read this knowledgebase article?
https://developer.arm.com/documentation/ka002218/latest/
It should explain in detail what you need to do before starting the application and how to start it.
Hello Hans Schneebauer thanks for your reply. I went through the document and my code seems to implement correctly the procedure. To test the jump I tried to set the address to the bootloader address (0x08000000) and it correctly jumps and re-execute it. When I set the RAM address from where I want to execute the application code, 0x20000000, it doesnt. I wonder if the issue is to be found in the memory allocation.My bootloaded linker script is:
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; *************************************************************
LR_IROM1 0x08000000 0x00020000 { ; load region size_region ER_IROM1 0x08000000 0x00020000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } RW_IRAM2 0x24020000 0x00080000 { ; RW data .ANY (+RW +ZI) } }
My application linker:
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) } }