0
votes

I'd like to do a jump to bootloader from application on STM32 Blue Pill STM32F103C8T6. My approach looks that: - Write to BKP->DR1 any value; - Do a reset (NVIC_SystemReset()); - A the beginning of main, check if BKP->DR1 != 0, than set it to 0 and jump to boot;

Dubugging shows, that core jumps far away (0xfffffffe) and nothing happens. My code:

/*
 * bootloader.c
 *
 *  Created on: 28.03.2020
 *      Author: Admin
 */

#include "stm32f10x.h"
#include "../Logger/logger.h"
#include "core_cm3.h"

#define ADDR 0x1FFFF000

void (*f_boot_jump)();

void boot_jump_to_boot ()
{

    f_boot_jump = (void (*)(void)) (*((uint32_t *)(ADDR + 4)));
    __disable_irq();
    __DSB();
    SCB->VTOR = (uint32_t) ADDR;
    __DSB();
    __ISB();
    __set_MSP(*(__IO uint32_t*) ADDR);
    f_boot_jump();

}

void boot_init()
{
    RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
    PWR->CR |= PWR_CR_DBP;

    if (BKP->DR1 != 0) //DR != 0 means, that boot request has been sent
    {
        BKP->DR1 = 0;
        RCC->APB1ENR &= ~RCC_APB1ENR_PWREN;
        RCC->APB1ENR &= ~RCC_APB1ENR_BKPEN;
        PWR->CR &= ~PWR_CR_DBP;
        RCC->CFGR &= ~RCC_CFGR_SW;
        RCC->CR &= ~RCC_CR_PLLON;
        RCC->CR &= ~RCC_CR_HSEON;
        boot_jump_to_boot();
    }

}

void boot_write_boot_request()
{
    BKP->DR1 = 0x1;
    NVIC_SystemReset();
}

SS from IDE: memory registers

I have no idea why it does not work. More over, before jump memory in the area of 0x1FFFF000 looks ok: Before jump

and here is after failing jump to boot: after jump Maybe my chip is fake? ST Utility shows correct values (Device ID, flash size, MediumDensity), but it can means nothing. When I'm using the BOOT pins, the bootloader is loaded properly and STM flashloader recognize it. Even if my chip is a fake, the embedded bootloader works so I can't figure out the reason, why jump from application does not work.

1
Is that because you do a complete system reset?SamR
I decided to do system reset, to enter to bootloader with "reset-like" conditions (interrupts, clock, etc.). This is why I'm writing byte to backup register, and at the beginning of main, before whole initialization I'm trying jump to boot if BKP is set.Jacek S
BKP is a part of RTC isnt it? Can you ensure your BKP has the right values before reset?SamR
The BKP is handled correctly, after reset with bootloader request, the code is executed correctly (after reset BKP->DR1 has before-reset value, than in boot_init I do jump to bootloader) - but the issue is with this jump.Jacek S

1 Answers

1
votes

I am jumping to bootloader on my stm32l4 chip. I have had success with the following code:

static void JumpToBootloader(void) 
{
  void (*SysMemBootJump)(void);
  volatile uint32_t addr = 0x1FFF0000;
  HAL_RCC_DeInit();

  SysTick->CTRL = 0;
  SysTick->LOAD = 0;
  SysTick->VAL = 0;
  __disable_irq();
  __HAL_RCC_SYSCFG_CLK_ENABLE();           //make sure syscfg clocked
  __DSB();
  __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();  //remap system memory to address 0x0000000
  __DSB();
  __ISB(); 
  SCB->VTOR = 0;                           //set vector table offset to 0
  SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
  __set_MSP(*(uint32_t *)addr);
    SysMemBootJump();
}

and

int main(void)
{
// Check to see if we need to go to DFU mode (testing only)
  __HAL_RCC_PWR_CLK_ENABLE();
  HAL_PWR_EnableBkUpAccess();  //use SRAM backup to store magic number;

  if (*(__IO uint8_t*)0x20040000 == 212)
  {  //is magic number correct?
    *(__IO uint8_t*)0x20040000 = 0;
    JumpToBootloader();
  }