Estoy tratando de reprogramar el NVM (banco de flash 2) mientras ejecuto el código del banco de flash 1 en el microcontrolador STM32L071CB.
Como dice AN4808 y AN4767, "la interfaz de memoria es capaz de leer ambos bancos en paralelo, o leer un banco mientras escribe en el otro ...", pero estoy experimentando algunos problemas:
Sé que me estoy perdiendo algo, pero no puedo encontrar lo que es. Tal vez alguien tuvo un problema similar? Estoy empezando a pensar que hay algo mal con el microcontrolador (la hoja de erratas señala algunos problemas con el mecanismo de cambio de banco dual, pero no debería ser un problema en mi caso, porque no estoy cambiando de banco en este momento).
Mi función funciona correctamente cuando se ejecuta desde la memoria RAM, pero prefiero que se ejecute desde el banco flash 1.
La función (1) a continuación es responsable de escribir medias páginas. El código (2) muestra la forma en que estoy llamando (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
Lectura-mientras-escritura tiene algunas limitaciones en el caso de la operación de programación múltiple. Ver RM0377 § 3.3.4 Escritura/borrado de la MVN - Media página del programa en la memoria de programa Flash página 82:
Cuando se inicia una operación de media página, la interfaz de memoria espera 16 direcciones/datos, abortando (con una falla grave) todos los accesos de lectura que no son de recuperación (consulte Recuperación y captación previa). Una búsqueda detiene la operación de media página. El contenido de la memoria permanece sin cambios, el error FWWERR se establece en el registro FLASH_SR.
Esto significa que no se permiten operaciones de búsqueda en la memoria flash mientras se alimenta la interfaz de memoria con las 16 palabras (cualquiera que sea el código que se ejecuta en el banco 1 y la programación de media página se realiza en el banco 2). Una vez que las 16 palabras se han enviado a la interfaz de memoria, puede reanudar la ejecución desde flash, es decir, durante la escritura física de los datos dentro del banco flash (suponiendo que su código se esté ejecutando en el otro banco).
En pocas palabras, debe ejecutar desde SRAM la alimentación de la interfaz de memoria con las 16 palabras y asegurarse de que las interrupciones no causen recuperación en la memoria flash (o enmascare todas las interrupciones o reubique los controladores de interrupciones y el vector de interrupciones en SRAM).
Nota: no existe tal limitación en el caso de la operación de programación única.
Jeroen3