Cómo sobrescribir la memoria flash en la serie STM32L

2

Estoy intentando escribir un patrón conocido (es decir, 0xFFFFFFFF o 0x00000000) sobre la memoria flash ya escrita, para invalidar partes de un sistema de archivos primitivo. Pero no me funciona en la serie STM32L como en la serie STM32F.

Estoy acostumbrado a la familia de microcontroladores STM32F, donde la memoria flash se borra a 0xFFFFFFFF y se escribe con 0. Puedes escribir lo que quieras para borrar la memoria, es decir,

 write 0x00001234 on top of 0xFFFFFFFF -> 0x00001234

y puedes escribir 0x00000000 (todos ceros) encima de cualquier cosa

 write 0x00000000 on top of 0x00001234 -> 0x0000000

Ahora estoy usando la familia STM32L (baja potencia), y la memoria flash es totalmente diferente. Se borra a 0x00000000 y se escribe con 1's. Sin embargo, no sé cómo escribir de forma fiable todos los unos. Por ejemplo, si borro, puedo hacer esto

 write 0x01020304 on top of 0x00000000 -> 0x01020304

pero si lo intento

 write 0xFFFFFFFF on top of 0x01020304 -> 0xFFFFFFBF !!!

Tenga en cuenta que la respuesta final tiene una B . No son todos unos. De hecho, si escribo bytes 0x00 a 0xFF en una página de memoria recién borrada, y luego escribo 0xFFFFFFFFFF en su totalidad, obtengo resultados muy erróneos:

ff ff ff bf ff ff ff ff ff ff ff ff ff ff ff fb
f7 ff ff ff fd ff ff ff ff ff ff f7 ff ff ff ff
fe ff ff ff ff ff ff ff ff ff ff 7f f7 ff ff ff
ff ff ff fb ff ff ff ef ff ff ff ff ff ff ff df
fe ff ff ff ff ff ff ff ff ff ff 7f f7 ff ff ff
ff ff ff fb ff ff ff ef ff ff ff ff ff ff ff ff
ff ff ff bf ff ff ff ff ff ff ff ff ff ff ff fb
f7 ff ff ff fd ff ff ff ff ff ff f7 ff ff ff df
f7 ff ff ff fd ff ff ff ff ff ff f7 fe ff ff ff
ff ff ff bf ff ff ff ff ff ff ff ff fd ff ff ff
ff ff ff fb ff ff ff ef ff ff ff ff ff ff ff bf
fe ff ff ff ff ff ff ff ff ff ff 7f fb ff ff ff
ff ff ff fb ff ff ff ef ff ff ff ff ff ff ff bf
fe ff ff ff ff ff ff ff ff ff ff 7f ff ff ff ef
f7 ff ff ff fd ff ff ff ff ff ff f7 fe ff ff ff
ff ff ff bf ff ff ff ff ff ff ff ff fb ff ff ff

Aquí está el pseudo código que estoy usando (FlashWrite es una envoltura alrededor de la biblioteca de periféricos estándar STM). Intenté escribir un patrón de 8 escrituras con los bits cambiados < < 1 cada vez, y eso me dio lo que quería (todos) pero no estoy seguro de que sea confiable.

 uint32_t pattern = 0x04030201;
 FlashErasePage(0x0801E000,FLASH_PASSWORD);
 for(int j=0;j<64;j++) {
    FlashWriteArray(0x0801E000 + 4*j,(uint8_t*)&pattern,4);
    pattern += 0x04040404;
 }

 for(int j=0;j<64;j++) {
#if 1
     // write once
     uint32_t pattern = 0xFFFFFFFF;
     FlashWriteArray(0x0801E000 + 4*j,(uint8_t*)&pattern,4);
#else
     // write shifting bit pattern
     uint32_t pattern = 0x01010101;
     for(int i=0;i<8;i++) {
        FlashWriteArray(0x0801E000 + 4*j,(uint8_t*)&pattern,4);
        pattern <<=1;
     }
#endif
    
pregunta Mark Lakata

1 respuesta

2

Algunos tipos de dispositivos de memoria no volátil utilizan una lógica de corrección de errores que agrega unos pocos bits adicionales a cada fragmento programable (por ejemplo, 5 bits por 16, 6 por 32, 7 por 64, 8 por 128, etc.) En general el código de corrección de errores se elige de modo que todos los bits en blanco sean una representación válida; en algunos casos, pero no en todos, también se puede elegir de modo que todos los bits programados también sean una combinación válida. Para simplificar, asumiré un código con el que se guarda cada grupo de 4 bits con 3 bits de guardia. Calcule los bits de guarda de los tres bits de guarda como el xor de los bits de datos 0 + 1 + 3, 0 + 2 + 3 o 1 + 2 + 3. También asumiré que una palabra en blanco es cero.

Los 16 valores de código posibles son, por lo tanto,

3210 ABC    3210 ABC    3210 ABC    3210 ABC
0000 000    0100 011    1000 111    1100 100
0001 110    0101 101    1001 001    1100 010
0010 101    0110 110    1010 010    1110 001
0011 011    0111 000    1011 100    1111 111

Cuando se lee un nybble de memoria, el sistema puede ver qué bits ABC deben estar de acuerdo con la tabla. Si uno de los siete bits de la palabra se lee mal, la combinación de bits ABC que no coinciden con el valor calculado indicará qué bit fue incorrecto.

Supongamos que un sistema de memoria utiliza el código de 16 bits que se muestra arriba, y uno quería sobrescribir un valor de byte de 1110 (ECC bits 001) con un valor de 1000 (ECC bits debería ser 111). El efecto neto sería que el sistema escribiría 1000 con bits de ECC de 001. Cuando se leen los datos, el sistema vería que para un valor de 1000, los bits de ECC deberían ser 111 pero en su lugar son 001. El hecho de que los bits A y B están equivocados significa que el bit 0 de los datos estaba equivocado y debería voltearse; por lo tanto, el sistema leerá el valor como 1001 (cuyo ECC es correctamente 001).

En la mayoría de los casos, debería haber suficiente flexibilidad en el diseño de un código de corrección de errores para permitir que el conjunto de todos los bits y el conjunto de todos los bits se consideren como combinaciones válidas. Sin embargo, algunos sistemas no lo hacen. Si un código de corrección de errores requeriría que una palabra programada para todos los bits tenga dos o más bits ECC en blanco, entonces un intento de borrar una palabra que tenga esos bits programados probablemente fracasará visiblemente; los intentos de programar muchos otros valores probablemente producirían un estado que estaba a solo un error de bit de error en lugar de dos.

Realmente deseo que los diseñadores de memoria permitan que los datos se borren incluso si no permiten la mayoría de los otros patrones de sobrescritura. Especialmente con la memoria flash NAND, facilitaría mucho las operaciones.

    
respondido por el supercat

Lea otras preguntas en las etiquetas