STM32F0* 通过 BOOT0 高电平退出 DFU 模式

问题描述 投票:0回答:1

要求:将BOOT0保持为高电平,以便STM32在首次连接到计算机时处于DFU模式。计算机软件可以闪存或立即离开到 0x08000000 运行闪存程序。

问题:当 BOOT0 保持高电平时,DFU 离开命令不起作用。

潜在的解决方案:用户已经在 STMF4 产品上解决了这个问题,因为它具有 Cortex-M3/M4 https://community.st.com/t5/stm32-mcus-embedded-software/leave-dfu-while-boot0 -is-high-stm32f4/td-p/556307

取消注释此行也可以解决这些产品的问题。

#define USER_VECT_TAB_ADDRESS
但是我还没有找到 Cortex-M0 (STM32F072RBT) 的分步解决方案的资源

我尝试过重新定位向量表并从 SRAM 启动。然而,由于我从未找到明确的方法来做到这一点,我相信我所有的尝试都损坏了代码。

大图动机:发布 PCB 上没有按钮或开关的产品 (STM32F072RBT),并允许客户通过 USB 串行接口刷新并与其产品交互。

stm32 bootloader boot stm32f0 dfu
1个回答
0
投票

我试图为我正在开发的产品做一些相同的事情。 STM 代表建议以下解决方案:始终启动到您的应用程序,但当您的应用程序希望进入 DFU 模式时,向您尚未使用的 RAM 区域写入一个神奇值并触发软重置,然后在应用程序启动检查过程中尽早进行对于神奇值,而不是运行正常的启动序列,跳转到系统引导加载程序。

您需要在 AN2606 中查找芯片的正确系统引导加载程序地址。下面的代码使用 STM32C011xx 的地址


// See Section STM32C011xx devices bootloader in AN2606
#define STM32C011xx_SYSTEM_BL_START_ADDR 0x1FFF0000 // FIXME: use address for your chip

// Pick somewhere in RAM that isn't currently used (soft reset doesn't wipe RAM itself)
#define STM32_SYSTEM_BL_MAGIC_ADDR 0x200003FC

// Something unique
#define STM32_SYSTEM_BL_MAGIC_VALUE 0xC0C1C2C3

void Reboot_To_Dfu(void)
{
  *((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) = STM32_SYSTEM_BL_MAGIC_VALUE;

  // Memory barriers
  __DSB();
  __ISB();

  // Soft reset
  NVIC_SystemReset();
  while (1);
}

void Handle_Dfu_Switch(void)
{
  // Check if we should go into bootloader mode
  if (*((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) == STM32_SYSTEM_BL_MAGIC_VALUE) {
    // Reset our trigger
    *((volatile uint32_t *) STM32_SYSTEM_BL_MAGIC_ADDR) = 0x00000000;

    uint32_t stack_pointer = ((const uint32_t *) STM32C011xx_SYSTEM_BL_START_ADDR)[0];
    uint32_t jump_addr = ((const uint32_t *) STM32C011xx_SYSTEM_BL_START_ADDR)[1];

    // Redirect vector table
    SCB->VTOR = STM32C011xx_SYSTEM_BL_START_ADDR;

    // Change MSP and PSP
    __set_MSP(stack_pointer);
    __set_PSP(stack_pointer);

    // Memory barriers
    __DSB();
    __ISB();

    void (*SysMemBootJump)(void) = (void (*)(void)) (jump_addr);
    SysMemBootJump();

    while (1);
  }
}

在您的 system_stm32xyz.c 中(其中

xyz
取决于您的芯片)将此行放在
SystemInit
函数的顶部:

void SystemInit(void)
{
  // Consider jumping to DFU instead of normal boot
  Handle_Dfu_Switch();

  // typical SystemInit code continues here...
}

我最终没有使用这个,所以我不是 100% 它有效,如果你尝试一下并且它对你有效,我会很高兴知道。

© www.soinside.com 2019 - 2024. All rights reserved.