我正在使用具有两个闪存库的 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)告诉我们:
- 如果尚未解锁,则解锁 OPTLOCK 位。
- 在 FLASH_OPTSR_PRG 寄存器中设置新的所需 SWAP_BANK_OPT 值。
- 通过设置 FLASH_OPTCR 寄存器中的 OPTSTART 位来启动选项字节更改序列。
- 一旦选项字节更改完成,FLASH_OPTSR_CUR 包含预期的 SWAP_BANK_OPT 值,但 FLASH_OPTCR 中的 SWAP_BANK 位尚未修改,并且存储库交换尚未生效。
- 强制系统重置或 POR。当复位上升时,bank swapping 有效(FLASH_OPTCR 中的 SWAP_BANK 值更新)并执行新固件。
我认为我这样做是正确的。我还检查了勘误表,在带有存储库切换的旧芯片中存在问题,但我使用的是最新V
版本。
我希望有人可以给我一个提示。