【问题标题】:STM32F103 Cannot jump to bootloader from appSTM32F103 无法从应用程序跳转到引导加载程序
【发布时间】:2020-07-10 13:16:02
【问题描述】:

我想从 STM32 Blue Pill STM32F103C8T6 上的应用程序跳转到引导加载程序。 我的方法看起来是: - 向 BKP->DR1 写入任意值; - 进行重置(NVIC_SystemReset()); - 一个main的开头,检查BKP->DR1 != 0,然后设置为0并跳转到boot;

Dubugging 显示,核心跳得很远(0xffffffffe)并且没有任何反应。 我的代码:

/*
 * 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();
}

来自 IDE 的 SS: memory registers

我不知道为什么它不起作用。 此外,在 0x1FFFF000 区域的跳转内存看起来没问题之前: Before jump

这是在跳转到引导失败后: after jump 也许我的芯片是假的? ST Utility 显示正确的值(设备 ID、闪存大小、MediumDensity),但它可能没有任何意义。 当我使用 BOOT 引脚时,引导加载程序已正确加载并且 STM 闪存加载程序可以识别它。 即使我的芯片是假的,嵌入式引导加载程序也可以工作,所以我无法弄清楚为什么从应用程序跳转不起作用。

【问题讨论】:

  • 是因为你做了一个完整的系统重置?
  • 我决定进行系统重置,以“类似重置”的条件(中断、时钟等)进入引导加载程序。这就是为什么我将字节写入备份寄存器,并且在 main 开始时,在整个初始化之前,如果设置了 BKP,我会尝试跳转到引导。
  • BKP 不是 RTC 的一部分吗?您能否确保您的 BKP 在重置前具有正确的值?
  • BKP 处理正确,在使用引导加载程序请求重置后,代码正确执行(重置 BKP->DR1 后具有重置前值,而不是在 boot_init 中我确实跳转到引导加载程序) - 但是问题在于这个跳跃。

标签: stm32 bootloader bluepill


【解决方案1】:

我正在跳转到我的 stm32l4 芯片上的引导加载程序。我已成功使用以下代码:

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();
}

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();
  }

【讨论】:

  • 谢谢。我不使用 HAL,但我找到了 stm32f1x 的驱动程序。不幸的是,我无法在这些驱动程序中找到 __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(),因此我仍在寻找使用 stdperiph 的工作解决方案。我还没有解决这个问题。
猜你喜欢
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 2019-12-26
  • 2014-10-24
  • 2022-09-29
  • 1970-01-01
  • 2023-01-31
  • 2013-08-15
相关资源
最近更新 更多