cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 Bootloader Fails to Jump to Application

ScottieZhang
Visitor

Hi everyone,

I'm new to bootloader development and currently working on my first STM32 bootloader project using an STM32F103. I’m trying to make a minimal bootloader that simply jumps to an application located at 0x08001000. There’s no USB, no UART, no DFU — just a basic check and jump.

#define APP_ADDRESS 0x08001000
typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();

  if (1)
  {
    HAL_GPIO_WritePin(CHIP_LED_GPIO_Port, CHIP_LED_Pin, GPIO_PIN_SET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(CHIP_LED_GPIO_Port, CHIP_LED_Pin, GPIO_PIN_RESET);
    HAL_Delay(100);

    __disable_irq();
    HAL_RCC_DeInit();
    SCB->VTOR = APP_ADDRESS;
    JumpAddress = *(__IO uint32_t*)(APP_ADDRESS + 4);
    JumpToApplication = (pFunction)JumpAddress;
    __set_MSP(*(__IO uint32_t*)APP_ADDRESS);
    JumpToApplication();
  }

  while (1)
  {
    HAL_GPIO_TogglePin(CHIP_LED_GPIO_Port, CHIP_LED_Pin);
    HAL_Delay(2000);
  }
}

The application is placed at 0x08001000, and the linker script includes:

// Application .ld File
MEMORY
{
  RAM    (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
  FLASH  (rx)  : ORIGIN = 0x08001000, LENGTH = 32K
}

Application main() loop:

//Application main.c
int main(void)
{
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM1_Init();

  /* Infinite loop */
  while (1)
  {
    HAL_GPIO_WritePin(CHIP_LED_GPIO_Port, CHIP_LED_Pin, GPIO_PIN_SET);
    HAL_Delay(200);
    HAL_GPIO_WritePin(CHIP_LED_GPIO_Port, CHIP_LED_Pin, GPIO_PIN_RESET);
    HAL_Delay(200);
  }
}

App vector table configuration:

In the application's system_stm32f1xx.c, I also added:

#define USER_VECT_TAB_ADDRESS
#define FLASH_BASE 0x08001000U

#if defined(USER_VECT_TAB_ADDRESS)
  #define VECT_TAB_BASE_ADDRESS   FLASH_BASE
  #define VECT_TAB_OFFSET         0x00000000U
#endif

So that SCB->VTOR is correctly set when the app runs(I hope).
After Bootloader JumpToApplication(), the application does not start — the LED in the app never blinks, even in Bootloader's while loop there is no LED bilnks. In some tests I’ve seen the PC end up at an unexpected address like 0x08000316, which is still in the bootloader region.

So is there anything wrong what I'm doing? Anything I might be missing from an app startup perspective?

Any advice would be greatly appreciated! Thanks 

1 REPLY 1
TDK
Super User

Don’t hope—run in debug and verify.

Hal delay will fail in application as you never enable interrupts.

even in Bootloader's while loop there is no LED bilnks

maybe debug bootloader before you debug the jump code.

If you feel a post has answered your question, please click "Accept as Solution".