cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with custom Bootloader

phyx
Associate

Hi all,

I have been developing a bootloader to facilitate OTA updates on an STM32F446 device. The OTA update works such that, when the device is powered on, it runs the bootloader, which is written at address 0x08000000 in the flash memory. I keep two copies of the firmware on the board, storing the version and location of the firmware using RTC backup registers.

When the bootloader starts, it checks the backup registers to determine if a new update is available (the update is downloaded by the firmware). If no updates are found, the bootloader jumps to the firmware located at either address 0x08020000 or 0x08040000 in the flash memory, depending on which storage contains the latest firmware. The bootloader switches to the firmware using the following function:

 

 

void bootloader_jump_to_user_app(uint32_t base_address)
{
  	void (*app_reset_handler) (void);
  	uint32_t msp_value = *(volatile uint32_t *) base_address;
  	uint32_t resethandler_address = *(volatile uint32_t *) (base_address + 4);

  	SCB->VTOR = base_address;

  	__set_MSP(msp_value);

  	app_reset_handler = (void*) resethandler_address;

  	app_reset_handler();
}

 

 

 In this function, the address of the firmware is passed on to this function.

On the initial boot, the device successfully jumps to the firmware. However, when a new update is detected, the firmware downloads the update using a SIM800C module, breaking the firmware into frames of 256 bytes. The new firmware is downloaded to address 0x08060000 in the flash memory. Once the update is complete, the backup register is updated (using a magic pattern) and the system resets via HAL_NVIC_SystemReset();.

After the reset, the bootloader detects the new update. The firmware is then copied to the location where the older version is stored, and HAL_NVIC_SystemReset(); is called again after the firmware file is successfully copied.

During this second boot, the base address changes after the update, but the bootloader fails to jump to the application. This issue occurs when the board is reset via software, but not when it is reset via hardware—where it correctly jumps to the new application.

How can I switch to the new application using a software reset?

I have already tried methods like deinitializing peripherals and interrupts using:

 

 

HAL_RCC_DeInit();
HAL_DeInit();
__disable_irq();

 

 

1 REPLY 1
FShah.1
Associate III

Hi,

I am working on a bootloader program. My application code is successfully transferred from the source to the controller via the serial port. But when the code attempts to set the reset handler and jump to the application code, it is failing.

I am using the STM32F446 microcontroller.

First, I copied the code to memory address 0x08040000. Then, bootloader copied to the application memory address, which is 0x08020000. The CRC of the application on the host side, the CRC at address 0x08040000, and the CRC at address 0x08020000 are all the same.

I checked the memory locations, and they have the same data. However, the jump_to_application function is not successful.

Blink LED Application: I changed the Flash address in linker file

/* Memories definition */

MEMORY

{

RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K

FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 128K

}

 

/*!< 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 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 0x00020000U /*!< Vector Table base offset field.

This value must be a multiple of 0x200. */

#endif /* VECT_TAB_SRAM */

#endif /* USER_VECT_TAB_ADDRESS */

 

 

Bootloader: jump_to_application function:

static void goto_application(void)
{
 
printf("Gonna Jump to Application\r\n");
 
 
 
// Set the Vector Table Offset Register (VTOR) to the address of the application
SCB->VTOR = ETX_APP_FLASH_ADDR;
// Get the application reset handler address
void (*app_reset_handler)(void) = (void*)(*((volatile uint32_t*) (ETX_APP_FLASH_ADDR + 4U)));//Application starting address
// Optionally turn off the LED
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
 
/* Reset the Clock */
HAL_RCC_DeInit();
HAL_DeInit();
__set_MSP(*(volatile uint32_t*) ETX_APP_FLASH_ADDR);
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
 
/* Jump to application */
app_reset_handler();    //call the app reset handler
}
Kindly advise on how to solve this problem. I am very close to the finish line, but something I am doing seems to be wrong! Please help. Thank you