2025-01-31 09:25 AM
Hi, I'm having trouble getting my application to run at a different firmware address. The end goal is to be able to have the application running, receive new firmware over the UART. The new firmware will be saved higher in Flash (0x08100000, LENGTH = 992K). On reset the bootloader will check this location for newer valid firmware, if valid move it to Bank1 (0x08008000, LENGTH = 1008K ) and run from Bank1. If the firmware isn't new, just run from Bank1.
Something things that may be relevant is the real application is using FreeRTOS and TouchGFX. For testing I just have an LED blink app.
In the debugger settings for the bootloader application I added the blink LED application under the "startup" tab. I'm flashing the firmware with the debugger.
Also, the LED does blink, even though the app reset values don't match. So I'm not sure yet if I'm chasing the correct issue, or the LED blink app is simple enough that it doesn't crash. My real app ends up with a hard fault when I jump to reset handler. So that's why I'm wondering if something isn't lining up correct at that step. In the linker file I have added some meta data for firmware values. The complete files are attached.
The LED blink app I have changed:
The linker file (FLASH.ld)
/* Memories definition */
MEMORY
{
BOOTLOADER (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* Bootloader size */
CURRENT_FW (rx) : ORIGIN = 0x08008000, LENGTH = 1008K /* Current Firmware size */
NEW_FW (rx) : ORIGIN = 0x08100000, LENGTH = 992K /* New Firmware size */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM3 (xrw) : ORIGIN = 0x20040000, LENGTH = 384K
}
The system_stm32, I uncommented the line #define USER_VECT_TAB_ADDRESS. The section is below.
/* 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
#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 SRAM1_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 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
In the .h I set
#define FLASH_BASE (0x08008000UL) /*!< FLASH(up to 2 MB) base address */
The bootloader linker file I changed:
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM3 (xrw) : ORIGIN = 0x20040000, LENGTH = 384K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* Bootloader region */
}
The bootloader jump to application function I added comments for the values. The one that seems to be the red flag is the .map file shows
Reset Handler should be at 0x080081bc but the value in the function is 0x80081bd
// Jump to application firmware
void jump_to_firmware(uint32_t firmware_address) {
// Disable interrupts
__disable_irq();
//CURRENT_FW_START = Hex:0x8008000
uint32_t initial_sp = *(volatile uint32_t *)CURRENT_FW_START; //initial_sp =Hex:0x200a0000 // Should point to stack pointer (e.g., 0x20020000)
// Set the vector table base address to the firmware's vector table
SCB->VTOR = firmware_address; //VTOR = Hex:0x8008000
// Set the stack pointer to the application's initial stack pointer
__set_MSP(*(volatile uint32_t *)firmware_address); // firmware_address=Hex:0x8008000
// Get the application's reset vector (entry point)
uint32_t app_reset_handler = *(volatile uint32_t *)(CURRENT_FW_START + 4); // Should be 0x080081BC
// Re-enable interrupts
__enable_irq();
// Jump to the application's reset handler
((void (*)(void))app_reset_handler)(); // app_reset_handler=0x80081bd
/* The .map file the Reset Handler should be at 0x080081bc
*(.isr_vector)
.isr_vector 0x08008000 0x1bc ./Core/Startup/startup_stm32l4s9zitx.o
0x08008000 g_pfnVectors
*(.text.Reset_Handler)
.text.Reset_Handler
0x080081bc 0x50 ./Core/Startup/startup_stm32l4s9zitx.o
0x080081bc Reset_Handler
*/
}
Is it OK the reset handler addresses don't match and my issue is something else going on
with my real code? Do I need to do something different with the linker file to get the address to match before I start
trying my real code?
Thanks for looking at this.