You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F405RG软件跳转DFU Bootloader异常求助:反复重启后进入模式

STM32F405RG软件跳转DFU Bootloader异常问题排查

问题描述

在STM32F405RG上通过软件尝试直接跳转到DFU Bootloader时,实际触发了软件复位并抛出RCC_FLAG_SFTRST标志。程序会反复执行跳转代码,数秒后才停留在Bootloader模式。禁用中断可一次性成功进入,但DFU模式需要启用中断才能完成代码上传,不清楚Bootloader跳回应用的原因。

跳转代码(在main中Init_HAL()后立即调用):

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

    HAL_RCC_DeInit();
    HAL_DeInit();
    
    // 关闭并重置SysTick
    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;

    // 未禁用中断,因为DFU模式需要
    // __disable_irq();
    
    // 重映射系统内存到0x00000000
    __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
    
    // 设置Bootloader跳转地址
    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
    
    // 设置主栈指针
    __set_MSP(*(uint32_t *)addr);
    
    // 跳转到Bootloader
    SysMemBootJump();
}

问题根源

核心原因是未清除所有挂起的中断请求。即使当前未开启全局中断,若之前有外设触发了中断且挂起标志未被清除,跳转至Bootloader后,Bootloader会重新开启中断,此时挂起的中断会立即触发,打乱Bootloader的执行流程,最终导致系统复位并回到应用程序。

HAL_DeInit()和HAL_RCC_DeInit()仅会重置外设和时钟,但不会清除NVIC中挂起的中断标志位,这是关键遗漏点。

修复方案

跳转前必须彻底清理中断环境,步骤如下:

  1. 先关闭全局中断,避免清理过程中触发新中断
  2. 手动清除所有NVIC挂起的中断请求
  3. 完成Bootloader映射、栈指针设置后,再重新开启全局中断

修改后的代码:

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

    // 1. 关闭全局中断,防止清理过程中触发新中断
    __disable_irq();

    // 2. 重置HAL和RCC外设
    HAL_RCC_DeInit();
    HAL_DeInit();

    // 3. 关闭并重置SysTick
    SysTick->CTRL = 0;
    SysTick->LOAD = 0;
    SysTick->VAL = 0;

    // 4. 清除所有NVIC挂起的中断请求
    for (uint32_t i = 0; i < (sizeof(NVIC->ICPR) / sizeof(NVIC->ICPR[0])); i++) {
        NVIC->ICPR[i] = 0xFFFFFFFF;
    }

    // 5. 重映射系统内存到0x00000000地址空间
    __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();

    // 6. 获取Bootloader入口地址(栈指针后的复位向量)
    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));

    // 7. 设置Bootloader的主栈指针
    __set_MSP(*(uint32_t *)addr);

    // 8. 重新开启全局中断,满足DFU模式需求
    __enable_irq();

    // 9. 跳转到DFU Bootloader
    SysMemBootJump();
}

关键说明

  • 清除NVIC挂起位是必须步骤:确保Bootloader启动后没有遗留的中断请求干扰执行
  • 先关中断再清理:避免在清理过程中产生新的中断挂起
  • 最后开启中断:保证DFU模式正常工作所需的中断功能

内容的提问来源于stack exchange,提问作者Rohit Josyula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 07:03:18