#embedded #stm32 #cortex-m #stm32h743
Вопрос:
Я использую STM32H753, который имеет два банка флэш-памяти. Для обновления прошивки я использую функцию обмена банковскими картами, чтобы микроконтроллер загружался в правильную версию.
Когда я меняю банки местами, микроконтроллер выходит из строя. Никаких сбоев или каких-либо других исключений. Отладчик сообщает мне, что ПК находится на 0x72c269e, а SP-на 0xbf00d7b4, но раньше они были другими, и я предполагаю, что эти адреса являются случайными.
В конце концов, включается сторожевой пес и сбрасывает mcu, после чего банки меняются местами, так что это сработало. Когда я меняю банки обратно, краха не происходит, и все работает нормально.
Вот код, который делает это:
pub fn swap_bank(flash: amp;mut stm32h7xx_hal::stm32::FLASH) -> Result<(), amp;'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: amp;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
версию.
Я надеюсь, что кто-нибудь сможет дать мне совет.
Комментарии:
1. Вы пытаетесь записать на флэш-память из того же банка, в котором находится драйвер флэш-памяти? Я не знаю подробностей этой конкретной части, но микроконтроллерам в целом не нравится, когда вы это делаете. Поэтому, если вы пытаетесь реализовать какой-либо загрузчик для программирования банка 1 или 2, вам необходимо разместить идентичный код драйвера флэш-памяти в обоих банках и выполнить из того, который не программируется.
2. Программа полностью расположена в одном банке. Обновление прошивки записывается во второй банк, после чего банки меняются местами и происходит перезагрузка для запуска новой прошивки. Только память второго банка записывается и стирается.
3. Что именно вы пишете во флэш-банке 2 ?
4. @GabrielT Итак, банк 1 содержит прошивку v1.0.0. Затем у меня появилась новая версия v1.0.1. Сервер запускает обновление и отправляет более 1.0.1. Устройство поместит данные в банк 2. Когда все будет закончено, сервер отправит CRC данных. Когда устройство подтвердит правильность CRC полученных и сохраненных данных в банке 2, оно инициирует обмен и перезагрузку. Версия, которую он запускает, теперь 1.0.1
5. Если он правильно работает с точкой останова, то, возможно, существует проблема с синхронизацией, которую можно избежать, когда точка останова вызывает задержку. Попробуйте добавить короткую задержку (возможно, nop(s)) перед циклом while.