Я пытаюсь перепрограммировать NVM (банк флэш-памяти 2) при выполнении кода из банка флэш-памяти 1 в микроконтроллере STM32L071CB.
Как указано в AN4808 и AN4767, «интерфейс памяти способен читать оба банка параллельно или читать один банк при записи в другой …», но у меня возникают некоторые проблемы:
Я знаю, что что-то упускаю, но не могу понять, что именно. Может у кого была похожая проблема? Я начинаю думать, что что-то не так с микроконтроллером (в листе ошибок указаны некоторые проблемы с механизмом переключения двух банков, но в моем случае это не должно быть проблемой, потому что я не переключаю банки прямо сейчас).
Моя функция работает правильно при выполнении из оперативной памяти, но я бы предпочел, чтобы она запускалась из флэш-банка 1.
Функция (1) ниже отвечает за запись половины страницы. Код (2) показывает, как я звоню (2).
(1)
void nvm_prog_write_halfpages(uint32_t* addr, uint32_t* data, uint32_t length){
// There can't be any previous alignment errors in the flash SR
if ((FLASH->SR & FLASH_SR_PGAERR_Msk) == FLASH_SR_PGAERR){
FLASH->SR = FLASH_SR_PGAERR; // clear any previous alignment errors
}
// Check if any operation was stopped previously due to code fetching
if ((FLASH->SR & FLASH_SR_FWWERR_Msk) == FLASH_SR_FWWERR){
FLASH->SR = FLASH_SR_FWWERR; // clear any previous fetch related errors
}
nvm_prog_unlock();
FLASH->PECR |= FLASH_PECR_PROG | FLASH_PECR_FPRG;
uint32_t cnt = 0;
while (length > 0){
*addr = *data; // Destination address will be increased by the hardware automatically
data++;
cnt++;
// When a half-page has been written
if (cnt == 16){
while ((FLASH->SR & FLASH_SR_BSY_Msk) == FLASH_SR_BSY)
;
cnt = 0;
addr += 16; // Write the next half-page
length--;
}
}
FLASH->PECR &= ~(FLASH_PECR_PROG | FLASH_PECR_FPRG);
nvm_prog_lock();
}
(2)
nvm_prog_erase_page((uint32_t *) 0x08010000); // Erase flash bank 2; it starts at 0x08010000
uint32_t dummydata[32], i;
for (i=0; i<32; i++){
dummydata[i] = i;
}
nvm_prog_write_halfpages((uint32_t *) 0x08010000, &dummydata[0], 2); // Write 2 half-pages at the beginning of flash bank 2
Чтение во время записи имеет некоторые ограничения в случае операции множественного программирования. См. RM0377 § 3.3.4 Запись/стирание NVM — Половина страницы программы во флэш-памяти программ, стр. 82:
Когда начинается операция с половиной страницы, интерфейс памяти ожидает 16 адресов/данных, прерывая (с серьезной ошибкой) все операции чтения, не являющиеся выборкой (см. Выборка и предварительная выборка). Выборка останавливает операцию с половиной страницы. Содержимое памяти остается без изменений, в регистре FLASH_SR устанавливается ошибка FWWERR.
Это означает, что операции выборки не разрешены во флэш-памяти при подаче в интерфейс памяти 16 слов (независимо от того, какой код выполняется в банке 1, а программирование половины страницы выполняется в банке 2). Как только 16 слов будут отправлены в интерфейс памяти, вы можете возобновить выполнение из флэш-памяти, то есть во время физической записи данных во флэш-банк (при условии, что ваш код выполняется в другом банке).
Короче говоря, вам нужно выполнить из SRAM загрузку интерфейса памяти 16 словами и убедиться, что прерывания не вызовут выборку во флэш-памяти (либо замаскируйте все прерывания, либо переместите обработчики прерываний и вектор прерываний в SRAM).
Примечание: в случае одиночной операции программирования такого ограничения нет.
Джероен3