2

I'm working on a boot-loader for STM32G491. The device is supposed to jump from the boot-loader (BL, located at 0x08000000) to the application (APP, located at 0x08008000).

When I flash the APP through the STM32 CubeProgrammer (and check the "Run" box), it runs perfectly fine. However, when jumping from BL to APP, the jump happens correctly (because I can see the expected UART outputs) but output of HAL_GetTick() does not change which leads me to believe that the interrupts are not triggering.

Here's the relevant code for BL:

Jump code - the input address is 0x08008000

void jump_to_address(uint32_t address)
{
    // Get application’s stack pointer (first word at APP_ADDR)
    uint32_t sp = *(__IO uint32_t *)address;

    // Get application’s reset handler (program counter) (second word at APP_ADDR + 4)
    uint32_t pc = *(__IO uint32_t *)(address + 4U);

    // disable interrupts
    __disable_irq();

    // Deinit peripherals used by application
    HAL_RCC_DeInit();
    HAL_DeInit();

     // disable SysTick
     SysTick->CTRL = 0;
     SysTick->LOAD = 0;
     SysTick->VAL = 0;

    // reconfigure vector table offset register to application
    SCB->VTOR = address;
    
    // set main stack pointer
    __set_MSP(sp);
    __set_PSP(sp);

    // jump to application's Reset_Handler
    pFunction jump = (pFunction)pc;
    jump();
}

And relevant code for APP:

Linker script STM32G491RETX_FLASH.ld

/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 112K
  /* Use flash-origin 0x08008000 when using with bootloader */
  FLASH    (rx)   : ORIGIN = 0x08008000,   LENGTH = 480K
  /* FLASH    (rx)   : ORIGIN = 0x08000000,   LENGTH = 512K */

}

I also set the vector table offset in system_stm32g4xx.c:

/************************* Miscellaneous Configuration ************************/
/* Note: Following vector table addresses must be defined in line with linker
         configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
     anywhere in Flash or Sram, else the vector table is kept at the automatic
     remap of boot address selected */
#define USER_VECT_TAB_ADDRESS  0x08000000U

#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
// #define VECT_TAB_SRAM
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00008000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/

I've also tried setting SCB->VTOR to 0x08008000 in main() also (before calling HAL_Init()). What am I missing?

8
  • 1
    Why are you disabling SysTick in the jump code? It should not be necessary. Of course, you must also enable interrupts after entering the application. Commented Sep 9 at 6:24
  • 4
    jump_to_address() calls __disable_irq(). Where/when are interrupts re-enabled? Commented Sep 9 at 7:07
  • 1
    Indeed. You disabled interrupts then wonder why they aren't triggering? Commented Sep 9 at 7:56
  • @Lundin you do not know it as OP app startup may enable it. Commented Sep 9 at 8:57
  • 1
    The bootloader correctly disables interrupts, then you are relying on the application to initialise and start interrupts as it needs. Rather relying on the de-initialision behaving correctly and being complete, it is safer to invoke a reset via the NVIC and perform the jump immediately after the reset so that you guarantee the MCU starts the application in the expected reset state. Commented Sep 11 at 12:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.