Problem to Jump from bootloader to application on STM32F412
Good morning everyone,
I am trying to modify a bootloader that is already in production and working.
My problem is that if I call the JumpToApplication() function right after peripheral initialization (as the production bootloader does), everything works perfectly.
However, if I call it from within the infinite loop or even after exiting the loop, as you can see from the attached code, the jump does not work.
I can't explain why.
Additionally, I wanted to ask two more things:
Is it necessary to define the array volatile uint32_t stack_arr[30]? I have never seen it in any bootloader.
In the statement pmain_app = (void (*)(void)) * (APPLICATION_START_ADDRESS + 1); I see that there is a +1 at the end, but in various examples, I always see +4. Yet it still works!!!
Can you give me some advice?
Thank you.
#include "main.h"
#include "dma.h"
#include "fatfs.h"
#include "spi.h"
#include "usb_host.h"
#include "gpio.h"
#include "crc.h"
extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
extern TIM_HandleTypeDef htim11;
static uint16_t tim_boot_x1ms = 0;
volatile static uint8_t timRefreshDisplay_x1ms = 0;
void SystemClock_Config(void);
void MX_USB_HOST_Process(void);
void JumpToApplication(void);
int main(void)
{
volatile uint32_t stack_arr[30] = {0}; // Allocate some stack
// just to show that
// the SP should be reset
// before the jump - or the
// stack won't be configured
// correctly.
HAL_Init();
SystemClock_Config();
static void JumpToApplication(void)
MX_GPIO_Init();
__enable_irq();
MX_DMA_Init();
MX_SPI1_Init();
MX_USB_HOST_Init();
MX_FATFS_Init();
MX_CRC_Init();
//JumpToApplication(); //JumpToApplication called here works fine
static bool endLoop = false;
while(!endLoop)
{
MX_USB_HOST_Process();
retStatus_t ret = USB_FW_Update_Process();
switch(ret)
{
case retNothing:
break;
case retJump:
__disable_irq();
endLoop = true;
break;
case retReset:
NVIC_SystemReset();
break;
}
}
JumpToApplication();
}
void JumpToApplication(void)
{
//Deinit all peripherals
HAL_SPI_MspDeInit(&hspi1);
HAL_TIM_Base_DeInit(&htim11);
HAL_CRC_MspDeInit(&hcrc);
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
__HAL_RCC_DMA2_CLK_DISABLE();
__HAL_RCC_SPI1_CLK_DISABLE();
__HAL_RCC_TIM1_CLK_DISABLE();
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
void (*pmain_app)(void);
__disable_irq();
SCB->VTOR = (uint32_t)APPLICATION_START_ADDRESS;
__set_MSP((uint32_t)*APPLICATION_START_ADDRESS);
pmain_app = (void (*)(void)) * (APPLICATION_START_ADDRESS + 1);
// JUMP TO APP!
pmain_app();
}
