Skip to main content
Explorer
August 8, 2024
Solved

STM32U575QII6 custom bootloader not jumping to my program

  • August 8, 2024
  • 5 replies
  • 2127 views

Hi All,

I am implementing a custom bootloader on a STM32U575QII6, but it is not jumping to my program.

I have my bootloader in bank 1, and I have written my program to Flash at address 0x08014000 - within the same bank.

I have tried multiple things and followed different posts etc but nothing is working for me. There is nothing specific around the U5 series.

 

#define APPLICATION_ADDRESS 0x08014000

void (*pFunction)(void) = (void(*)(void)) APPLICATION_ADDRESS + 4;
HAL_RCC_DeInit();
HAL_DeInit();
__disable_irq();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
SCB->VTOR = (uint32_t)APPLICATION_ADDRESS;
__set_MSP(*(uint32_t*) APPLICATION_ADDRESS);
__DSB();
__ISB();
__enable_irq();
(*pFunction)();

 

Any help would be appreciated, thanks!

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

    Thank you for the replies. They were useful!

    In the end it was @korek1222s answer that helped, thank you!

    My code was jumping to the correct place it just wasn't set up correctly...

    I was jumping to the reset handler of my application from my boot loader but I forgot to change the vector table offset in my application before writing it to flash. Once I changed this it was jumping to my application and running it successfully!

    5 replies

    Visitor II
    August 8, 2024

    I had simmilar problem while making jump to app function. I found out in stm32u575 I had to disable MX_ICACHE_Init() or comment in main app before jumping to the flash destinated addres.

    MX_ICACHE_Init();

     

     

    joeSDAuthor
    Explorer
    August 8, 2024

    Thank you for the reply. 

    I have tried commenting out MX_ICACHE_Init() and running it again but it does not work. It jumps to HAL_RCC_OscConfig instead even though the function pointer is set up correctly. 

    Visitor II
    August 8, 2024

    #define APPLICATION_ADDRESS 0x08014000

     

    void (*pFunction)(void) = (void(*)(void)) (*(uint32_t*)(APPLICATION_ADDRESS + 4));

    HAL_RCC_DeInit();

    HAL_DeInit();

    __disable_irq();

    SysTick->CTRL = 0;

    SysTick->LOAD = 0;

    SysTick->VAL = 0;

    SCB->VTOR = (uint32_t)APPLICATION_ADDRESS;

    __set_MSP(*(uint32_t*) APPLICATION_ADDRESS);

    __DSB();

    __ISB();

    __enable_irq();

    (*pFunction)();

    Maybe try this

     

    joeSDAuthor
    Explorer
    August 8, 2024

    I gave this a try and it sets the function pointer to 0x08017c1d when I would want it to be 0x08014000.

    Not sure why it sets it incorrectly though.

    Graduate II
    August 8, 2024

    0x8014000 is an address of a table, not executable code.

    You want to be jumping to Reset_Handler on the application side. Check address via .MAP file output by Linker

    Graduate II
    August 8, 2024

    Hard pressed to believe it's not actually jumping.

    I wouldn't put the address in a local and change the stack, but it should branch some place. Instrument better so you have visibility as to what happens and sanity check the pointers and values.

    On the application side, make sure SystemInit sets the right address into VTOR.

    Do something early in Reset_Handler so you can confirm arrival there.

    Super User
    August 8, 2024

    See example jump to bootloader code here:

    How to jump to system bootloader from application ... - STMicroelectronics Community

    In particular note this line:

    > SysMemBootJump = (void (*)(void)) (*((uint32_t *) ((BootAddr[MCU] + 4))));

    What happens when you debug and step through? Should be straightforward to diagnose.

    Could also be due to not disabling interrupts so one gets triggered when __enable_irq happens but now the vector table is wrong.

    Graduate II
    August 8, 2024

    The desirable action when some one tells you to "Disable the Interrupts" is not to literally disable them at the MCU, but to tear down all the junk that you have generating them. The RAM contexts for instances and interrupt are likely to be entirely different from the loader to the application, unless specific care has been taken to hand things off, and you've got some kind of contract between the two sides.

    What the App wants is a "Quiet" environment to start, it will initialize it's own RAM allocations, and some when much later start up peripherals and interrupts. Figure that might take several hundred milli-seconds.

    You should check that the Vectors and App space isn't blank, ie all 0xFFFFFFFF

    Perhaps dump the first dozen Vectors you can see, so you can compare/review that against the image the linker generated.

    joeSDAuthorAnswer
    Explorer
    August 9, 2024

    Thank you for the replies. They were useful!

    In the end it was @korek1222s answer that helped, thank you!

    My code was jumping to the correct place it just wasn't set up correctly...

    I was jumping to the reset handler of my application from my boot loader but I forgot to change the vector table offset in my application before writing it to flash. Once I changed this it was jumping to my application and running it successfully!