首页 > 解决方案 > 交换闪存库时如何防止STM32H7崩溃

问题描述

我正在使用具有两个闪存库的 STM32H753。对于我的固件更新,我使用了银行交换功能,因此 mcu 引导到正确的版本。

当我交换银行时,微控制器崩溃。没有硬故障或任何其他异常。调试器告诉我,PC 位于 0x72c269e,SP 位于 0xbf00d7b4,但这些地址之前有所不同,我假设这些地址是随机的。

最终看门狗启动并重置MCU,然后交换银行,所以它确实有效。当我换回银行时,没有崩溃,一切正常。

这是执行此操作的代码:

pub fn swap_bank(flash: &mut stm32h7xx_hal::stm32::FLASH) -> Result<(), &'static str> {
    assert!(flash.optcr().read().optlock().bit_is_clear());

    // Get the current config
    let current_bank = get_current_bank(flash) != 1;
    let swapped_bank = !current_bank;

    // Config the new bank
    flash
        .optsr_prg()
        .modify(|_, w| w.swap_bank_opt().bit(swapped_bank));

    // Start the config write
    flash.optcr().modify(|_, w| w.optstart().set_bit());
    
    // Wait for the change to propegate
    while flash.optsr_cur().read().opt_busy().bit_is_set() {
        cortex_m::asm::nop();
    }

    // We're done, now we need to reboot
    Ok(())
}

pub fn get_current_bank(flash: &mut stm32h7xx_hal::stm32::FLASH) -> u8 {
    flash.optcr().read().swap_bank().bit() as u8 + 1
}

如果我在 while 循环之前放置一条 bkpt 指令,它会被命中两次(如果我继续,则两次都不会崩溃)。
如果我在 while 循环之后放了一条 bkpt 指令,那么第一次交换时它不会被命中。

参考手册(4.3.13)告诉我们:

  1. 如果尚未解锁,则解锁 OPTLOCK 位。
  2. 在 FLASH_OPTSR_PRG 寄存器中设置新的所需 SWAP_BANK_OPT 值。
  3. 通过设置 FLASH_OPTCR 寄存器中的 OPTSTART 位来启动选项字节更改序列。
  4. 一旦选项字节更改完成,FLASH_OPTSR_CUR 包含预期的 SWAP_BANK_OPT 值,但 FLASH_OPTCR 中的 SWAP_BANK 位尚未修改,并且存储库交换尚未生效。
  5. 强制系统重置或 POR。当复位上升时,bank swapping 有效(FLASH_OPTCR 中的 SWAP_BANK 值更新)并执行新固件。

我认为我这样做是正确的。我还检查了勘误表,在带有存储库切换的旧芯片中存在问题,但我使用的是最新V版本。

我希望有人可以给我一个提示。

标签: embeddedstm32cortex-mstm32h743

解决方案


推荐阅读