Ich versuche, den NVM (Flash-Bank 2) neu zu programmieren, während Code von Flash-Bank 1 im STM32L071CB-Mikrocontroller ausgeführt wird.
Wie AN4808 und AN4767 angeben, "ist die Speicherschnittstelle in der Lage, beide Bänke parallel zu lesen oder eine Bank zu lesen, während in die andere geschrieben wird ...", aber ich habe einige Probleme:
Ich weiß, dass mir etwas fehlt, aber ich kann nicht herausfinden, was es ist. Hatte vielleicht jemand ähnliche Probleme? Ich fange an zu glauben, dass etwas mit dem Mikrocontroller nicht stimmt (Errata-Blatt weist auf einige Probleme mit dem Dual-Bank-Umschaltmechanismus hin, aber das sollte in meinem Fall kein Problem sein, da ich gerade keine Bank wechsle).
Meine Funktion funktioniert ordnungsgemäß, wenn sie vom RAM-Speicher ausgeführt wird, aber ich möchte lieber, dass sie von der Flash-Bank 1 ausgeführt wird.
Die folgende Funktion (1) ist für das Schreiben von halben Seiten zuständig. Code (2) zeigt den Weg, den ich anrufe (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
Read-While-Write hat einige Einschränkungen im Falle eines Mehrfachprogrammiervorgangs. Siehe RM0377 § 3.3.4 Schreiben/Löschen der NVM - Programmhalbseite im Flash-Programmspeicher Seite 82:
Wenn eine Halbseitenoperation beginnt, wartet die Speicherschnittstelle auf 16 Adressen/Daten und bricht (mit einem harten Fehler) alle Lesezugriffe ab, die kein Abruf sind (siehe Abrufen und Vorabrufen). Ein Abruf stoppt die Halbseitenoperation. Der Speicherinhalt bleibt unverändert, der Fehler FWWERR wird im Register FLASH_SR gesetzt.
Dies bedeutet, dass im Flash keine Abrufoperation erlaubt ist, während die Speicherschnittstelle mit den 16 Wörtern gespeist wird (was auch immer der Code in Bank 1 läuft und die Halbseitenprogrammierung in Bank 2 durchgeführt wird). Sobald die 16 Wörter an die Speicherschnittstelle gesendet wurden, können Sie die Ausführung vom Flash aus fortsetzen, dh während des physischen Schreibens der Daten in die Flash-Bank (vorausgesetzt, Ihr Code läuft in der anderen Bank).
Kurz gesagt, Sie müssen vom SRAM aus die Speisung der Speicherschnittstelle mit den 16 Wörtern ausführen und sicherstellen, dass die Interrupts keinen Abruf im Flash-Speicher verursachen (entweder alle Interrupts maskieren oder Interrupt-Handler und Interrupt-Vektor im SRAM verschieben).
Hinweis: Bei der Einzelprogrammierung gibt es diese Einschränkung nicht.
Jeroen3