Hello, I am trying to build a custom bootloader which is jumping in the application. In order to do this in a first approach, i wrote a Bootloder which jumps as follows:
For the application I changed the VET_TAB_OFFSET to 0x000A0000UL.
In Keil Settings Target I changed the Read/only Memory Areas:
IROM1 : Start 0x80A000 Size 0x60000
In the Target Options I unchecked Use Memory Layout from Target Dialog
For R/O Base I put 0x080A0000
My scatter file for the application:
LR_IROM1 0x080A0000 0x00060000 { ; load region size_region ER_IROM1 0x080A0000 0x00060000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } RW_IRAM1 0x20000000 0x00020000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x24000000 0x00080000 { .ANY (+RW +ZI) } } LR_IROM2 0x08100000 0x00100000 { ER_IROM2 0x08100000 0x00100000 { ; load address = execution address .ANY (+RO) } }
For the Bootloader
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x000A0000 { ; load region size_region ER_IROM1 0x08000000 0x00A0000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) .ANY (+XO) } RW_IRAM1 0x20000000 0x00020000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x24000000 0x00080000 { .ANY (+RW +ZI) } } LR_IROM2 0x08100000 0x00100000 { ER_IROM2 0x08100000 0x00100000 { ; load address = execution address .ANY (+RO) } }
I use Keil with the MDK Plus Toolchain on the STM32H753.
I do the jump on the bootloader as follows and nothing happens:
void start_app() { uint32_t JumpAddress = *(volatile uint32_t*) (JUMP_ADDR+4); void (*jump_to_application)(void)= (void*) JumpAddress; HAL_RCC_DeInit(); __disable_irq(); __set_MSP(*(__IO uint32_t*) JUMP_ADDR); // Disable systick timer and reset it to default values SysTick->CTRL = 0; SysTick->LOAD = 0; SysTick->VAL = 0; //__disable_irq(); //__DSB(); SCB->VTOR = JUMP_ADDR; jump_to_application(); }
What could be the reason?
As far as I know, our knowledgebase article covers all aspects of jumping from a bootloader to an application. As my colleague already mentioned, you need to use a debugger to see what happens. If you have an ST board, there should be an ST-Link on it. Single step through your code to see what happens. Does your bootloader jump to an unknow address, or does the jump cause an exception or.…
Does your hardware have an enabled on-chip or external watchdog timer that needs to be fed?
It jumps to the reset Handler and then just resets to the bootloader again.
It also doen't jump in here:
if( CONTROL_SPSEL_Msk & __get_CONTROL( ) ) { /* MSP is not active */ __set_MSP( __get_PSP( ) ) ; __set_CONTROL( __get_CONTROL( ) & ~CONTROL_SPSEL_Msk ) ; }
I have set also the projects up as a multiproject workspace according to this : https://developer.arm.com/documentation/ka005060/latest/
Still the debugger lands in the reset handler.
If your CPU is already using the MSP, it also does not require to execute this piece of code.
Then, bootloader and application must not have overlapping flash regions. So in the bootloader project, remove the LR_IROM2.
Also with what parameter do you call BootJump() function? And, is at the address you give there already some valid application flashed?
You should see in the debug session when stepping into the BootJumpASM() in the CPU registers the if the values are plausible or not. What values do you see there?