Skip to main content
Explorer
April 4, 2025
Solved

Cutom bootloader STM32u575

  • April 4, 2025
  • 3 replies
  • 635 views

Hello,

I am trying to realise my own bootloader on my STM32U575 and have found the following article:
https://community.st.com/t5/stm32cubeide-mcus/stm32u575-custom-bootloader-bootloader/td-p/584218
Unfortunately this does not work for me.

 

I am using a STM32u575VGT and the following code:

  • Function at main.c
static void _bootJumpToFirmware() {
	typedef void (*pFunction)(void);
	#define APPLICATION_ADDRESS 0x0803C000
	pFunction JumpToApplication;
	JumpToApplication = (pFunction) (*(volatile uint32_t*) (APPLICATION_ADDRESS + 4));
	__set_MSP(*(uint32_t*) APPLICATION_ADDRESS);
	JumpToApplication();
}​
  • STM32U575VGTX_FLASH.ld in bootloader project
/* Memories definition */
MEMORY
{
 RAM	(xrw)	: ORIGIN = 0x20000000,	LENGTH = 768K
 SRAM4	(xrw)	: ORIGIN = 0x28000000,	LENGTH = 16K
 FLASH	(rx)	: ORIGIN = 0x08000000,	LENGTH = 240K
}​
  • STM32U575VGTX_FLASH.ld in main project
/* Memories definition */
MEMORY
{
 RAM	(xrw)	: ORIGIN = 0x20000000,	LENGTH = 768K
 SRAM4	(xrw)	: ORIGIN = 0x28000000,	LENGTH = 16K
 FLASH	(rx)	: ORIGIN = 0x0803C000,	LENGTH = 784K
}​

ICACH is disabled.
I have flashed the main project and the bootloader project and checked with the STM32CubeProgrammer that from 0x8000000 or from 0x0803C000 code is contained in the flash with the expected code length.
When I start the controller, I can see that the bootloader is running (with LEDs on my board) and at the point where it should jump to the firmware, the controller seems to stop or the firmware does not start.

What can I investigate to find the problem?

    This topic has been closed for replies.
    Best answer by rohe

    The following problems have arisen, which I have now been able to solve:

    • It does not work if i programm the main project with the STM32CubeIDE ==> If I compile it with the IDE and programm it with the STM32CubeProgrammer it works
    • It is not possible to call the _bootJumpToFirmware() function in a interrupt service routine. ==> I had to set a flag and execute the function in the main code

    With these two steps, the function itself, the adaptation in the two linker files and the adaptation in system_stm32u5xx.c, the jump to the firmware now works.

    @Tesla DeLorean thanks for the tip with the vector table.

     

    3 replies

    Graduate II
    April 4, 2025

    Make sure the SystemInit code in each sets SCB->VTOR to the appropriate Vector Table address.

    Would suggest you try stepping the transition code, making sure it enters your Reset_Handler 

    Have a UART working along with a HardFault_Handler that outputs actionable data.

    roheAuthor
    Explorer
    April 4, 2025

    I have set

    /************************* Miscellaneous Configuration ************************/
    /*!< Uncomment the following line if you need to relocate your vector Table in
     Internal SRAM. */
    /* #define VECT_TAB_SRAM */
    #define VECT_TAB_OFFSET 0x0003C000UL /*!< Vector Table base offset field.
     This value must be a multiple of 0x200. */
    /******************************************************************************/

    in system_stm32u6xx.c of the main project
    With the SystemInit function below the SCB_->VTOR should be set

    void SystemInit(void)
    {
     /* FPU settings ------------------------------------------------------------*/
     #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
     SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
     #endif
    
     /* Reset the RCC clock configuration to the default reset state ------------*/
     /* Set MSION bit */
     RCC->CR = RCC_CR_MSISON;
    
     /* Reset CFGR register */
     RCC->CFGR1 = 0U;
     RCC->CFGR2 = 0U;
     RCC->CFGR3 = 0U;
    
     /* Reset HSEON, CSSON , HSION, PLLxON bits */
     RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON);
    
     /* Reset PLLCFGR register */
     RCC->PLL1CFGR = 0U;
    
     /* Reset HSEBYP bit */
     RCC->CR &= ~(RCC_CR_HSEBYP);
    
     /* Disable all interrupts */
     RCC->CIER = 0U;
    
     /* Configure the Vector Table location add offset address ------------------*/
     #ifdef VECT_TAB_SRAM
     SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
     #else
     SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
     #endif
    }

    If i call disassembly at the _bootJumpToFirmware function i get

    515 static void _bootJumpToFirmware() {
     _bootJumpToFirmware:
    08002330: push {r7, lr}
    08002332: sub sp, #8
    08002334: add r7, sp, #0
    522 	JumpToApplication = (pFunction)(*((uint32_t *)((APPLICATION_ADDRESS) + 4U)));
    08002336: ldr r3, [pc, #32] @ (0x8002358 <_bootJumpToFirmware+40>)
    08002338: ldr r3, [r3, #0]
    0800233a: str r3, [r7, #4]
    523 	__set_MSP(*(uint32_t*) APPLICATION_ADDRESS);
    0800233c: ldr r3, [pc, #28] @ (0x800235c <_bootJumpToFirmware+44>)
    0800233e: ldr r3, [r3, #0]
    08002340: str r3, [r7, #0]
    1155 __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
    08002342: ldr r3, [r7, #0]
    08002344: msr MSP, r3
    1156 }
    08002348: nop 
    524 	JumpToApplication();
    0800234a: ldr r3, [r7, #4]
    0800234c: blx r3
    525 }

    At 0800234c the R3 register contains 0x8059cd1

    In the End the Code reaches the Infinite Loop in startup_stm32u575vgtx.s at 0x8002a20 with the call structure

    - 0x805c970
    - 0x805c804
    - <signal handler called>() at 0xfffffb8
    - WWDG_IRQHandler() at startup_stm32u575vgtx.s:115 0x8002a20

     

    I have set a breakpoint in the reset_handler in startup_stm32u575vgtx.s of the bootloaderproject in line 62, but the breakpoint never triggers.

    roheAuthorAnswer
    Explorer
    April 7, 2025

    The following problems have arisen, which I have now been able to solve:

    • It does not work if i programm the main project with the STM32CubeIDE ==> If I compile it with the IDE and programm it with the STM32CubeProgrammer it works
    • It is not possible to call the _bootJumpToFirmware() function in a interrupt service routine. ==> I had to set a flag and execute the function in the main code

    With these two steps, the function itself, the adaptation in the two linker files and the adaptation in system_stm32u5xx.c, the jump to the firmware now works.

    @Tesla DeLorean thanks for the tip with the vector table.