Как предотвратить сбой на STM32H7 при замене флеш-банков
Я использую STM32H753 с двумя флеш-банками. Для обновления прошивки я использую функцию смены банков, поэтому микроконтроллер загружается до правильной версии.
Когда меняю местами банки, вылетает микроконтроллер. Никаких аппаратных сбоев или каких-либо других исключений. Отладчик сообщает мне, что ПК находится по адресу 0x72c269e, а SP - по адресу 0xbf00d7b4, но раньше они были другими, и я предполагаю, что эти адреса случайны.
В конце концов срабатывает сторожевой таймер и сбрасывает микроконтроллер, после чего банки меняются местами, так что он работал. Когда меняю банки обратно, вылета нет и все работает нормально.
Вот код, который это делает:
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
}
Если я помещаю инструкцию bkpt перед циклом while, она срабатывает оба раза (и если я продолжу, оба раза не произойдет сбоя).
Если я помещаю инструкцию bkpt после цикла while, она не срабатывает при первом переключении.
Справочное руководство (4.3.13) говорит нам следующее:
- Разблокируйте бит OPTLOCK, если он еще не разблокирован.
- Установите новое желаемое значение SWAP_BANK_OPT в регистре FLASH_OPTSR_PRG.
- Запустите последовательность изменения байта опции, установив бит OPTSTART в регистре FLASH_OPTCR.
- После того, как изменение байта опции завершено, FLASH_OPTSR_CUR содержит ожидаемое значение SWAP_BANK_OPT, но бит SWAP_BANK в FLASH_OPTCR еще не был изменен, и смена банка еще не вступила в силу.
- Принудительный сброс системы или POR. Когда значение сброса увеличивается, смена банков вступает в силу (значение SWAP_BANK обновляется в FLASH_OPTCR), и должна выполняться новая прошивка.
Я думаю, что делаю это правильно. Я также проверил ошибки, и в более старом кремнии были проблемы с переключением банка, но я использую новейший
V
доработка.
Надеюсь, кто-нибудь подскажет.