Escritura frecuente en una memoria no volátil

9

Estoy diseñando un dispositivo que ajusta automáticamente su posición física a medida que cambia la temperatura. Si el dispositivo se apaga o se desconecta la alimentación, el dispositivo debe recordar su última temperatura y posición. Tengo la capacidad de almacenar estos valores en EEPROM, pero el problema es que la posición y la temperatura podrían estar cambiando muy rápidamente. Si tuviera que escribir la temperatura y la posición en la EEPROM después de cada cambio, eso (1) ralentizaría un poco el firmware y (2) probablemente eliminaría la EEPROM después de un año o dos. Entonces, como lo veo, mis opciones son las siguientes ...

1) use un condensador / batería para mantener el dispositivo encendido por un corto tiempo después de que se pierda la alimentación, de modo que solo pueda escribir los valores en EEPROM en ese momento. No me gusta esto porque el tablero está un poco hambriento de poder y esto requeriría una gran capitalización. Y no tengo un montón de espacio libre. Y no quiero el costo adicional de una batería y el soporte de la batería / o una gran capitalización.

2) use F-RAM en lugar de EEPROM para poder escribirle un billón de veces sin agotarlo. No me gusta esta opción porque FRAM es un poco más caro que EEPROM y esto es para un producto de producción (no solo uno).

3) Solo escriba la posición y la temperatura cada 5 minutos aproximadamente. De esa manera, siempre tengo una posición / temperatura bastante reciente registrada, pero no estoy escribiendo cada segundo, por lo que mi programa no se ralentiza y la EEPROM no morirá tan rápido. Esta parece ser mi mejor opción.

¿Alguien más tiene alguna sugerencia en la que no esté pensando?

    
pregunta PICyourBrain

5 respuestas

9

Lo que necesitas es una técnica llamada nivelación de desgaste . No escribe sus datos cada vez en la misma ubicación en la EEPROM, pero utiliza algún algoritmo para usar diferentes ubicaciones. He leído sobre complejos algoritmos de nivelación de desgaste, pero no sabría por qué el siguiente método simple no funcionaría.

Agregue a sus datos un contador de 24 bits, de modo que su bloque de datos tenga, por ejemplo, una longitud de 8 bytes. Las páginas en una 24AA64 tienen una longitud de 32 bytes, por lo que una EEPROM de 64 kb contiene 256 páginas. De la hoja de datos:

  

"Al hacer una escritura de menos de 32 bytes   Los datos en el resto de la página se actualizan.   junto con los bytes de datos que se escriben.   Esto obligará a toda la página a soportar un   ciclo de escritura, por esta razón la resistencia es   especificado por página. "

por lo que no tiene sentido usar bloques de datos más pequeños que una página de 32 bytes.

Mira el contador de la primera página. Si es cero, utilizó el número máximo de ciclos de escritura para esa página, de modo que pase a la página siguiente y verifique ese contador. Repita hasta que encuentre un contador > cero. Esa es la página que estás usando actualmente. Las EEPROM de Microchip tienen una resistencia de 1 millón de ciclos, que puede aumentar a 256 millones con el ejemplo dado de un máximo de 32 bytes por bloque en una EEPROM de 64 kb. Eso debería ser suficiente para sobrevivir a su producto: 40 años si escribe una vez cada 5 segundos (!).

Querrá inicializar su EEPROM en el primer uso. ¿Cómo sabes cuándo es eso? Use la última página para escribir una firma única después de la inicialización. Compruebe en cada encendido si la firma está allí. Si no es así, el dispositivo tiene que ser inicializado. Puede preajustar el contador en cada página con 0xF4240 (por 1 millón) o borrar todo a 0xFF y escribir el 0xF4240 cuando utilice la página por primera vez.
La inicialización de una EEPROM es necesaria porque a veces se escribe cierto patrón en el proceso de producción / prueba.

editar
La nivelación de desgaste debería resolver sus problemas, pero todavía quiero comentar sobre la solución del capacitor. Usted dice que la placa consume bastante energía, pero tal vez pueda aislar la energía del microcontrolador / EEPROM del resto de la placa con un diodo. Por lo tanto, es probable que solo necesite unos pocos mA cuando la alimentación principal se haya agotado. El 24AA64 escribe una página en menos de 5 ms, luego a 10 mA y una caída de voltaje permitida de 100 mV que necesitará

  

\ $ C = \ dfrac {I \ cdot t} {\ Delta V} = \ dfrac {10mA \ cdot 5ms} {100mV} = 500 \ mu F \ $

Fácil con un pequeño supercap.

lecturas adicionales
hoja de datos 24AA64
Tutorial de resistencia de EEPROM

    
respondido por el stevenvh
4

1) Una vez que haya iniciado el proceso de escritura, solo necesita alimentar la MCU / EEPROM y asegurarse de que las líneas de control no tengan problemas, I2C probablemente es preferible a SPI para esto. Solo necesita unos pocos mA durante unos pocos milisegundos, por lo que no debería ser una gran capitalización, y podría poner el MCU en suspensión una vez que se inicia la escritura. 3) probablemente puedas aplicar algo de inteligencia, por ej. Una retención: una vez escrito, siempre tiene un cierto tiempo antes de que otra escritura pueda suceder. O esperar hasta que el valor permanezca estable durante un tiempo antes de escribir.
También puede aumentar la resistencia distribuyendo los datos en varias ubicaciones. Microchip tiene algunas herramientas y amp; apuntes para calcular la resistencia de sus eeproms, lo que puede ser útil.

    
respondido por el mikeselectricstuff
3

Sugeriría usar un dispositivo flash orientado a bloques y utilizar un byte de cada bloque como indicador de modo. Mantener como invariante que casi todos los indicadores de modo serán programados; solo habrá un bloque donde el indicador de modo no está programado, pero el bloque anterior (ajuste si es necesario) sí lo está. Ese bloque será el que tenga los datos más recientes. Cuando ese bloque se llene, borre el siguiente bloque (tenga en cuenta que el bloque que se está borrando podría contener cualquier combinación de datos durante el ciclo de borrado, y que el invariante aún se mantendría), luego, una vez que se haya completado el borrado, programe el indicador de modo en lo que solía Sé el último bloque.

Será necesario proteger el suministro del flash lo suficientemente bien como para garantizar que cualquier intento de programar un byte tenga éxito o falle en su totalidad, pero no importará si se interrumpe un ciclo de borrado dejando un bloque lleno de datos arbitrarios, ya que el próximo intento de escribir una entrada de datos volverá a borrar ese bloque.

Si sus datos son de 16 bits, un chip de 64Kx8 tendrá más de 32,000 entradas. Escribir una entrada por segundo llenaría el chip aproximadamente 2.7 veces. Incluso un chip con una duración de "solo" ciclos de borrado de 10 K duraría más de 10 años. El uso de un chip más grande, o uno con una resistencia de 100 K, aumentaría la vida útil proporcionalmente.

    
respondido por el supercat
2

1) Posiblemente la opción más simple, aunque podría requerir cambios de hardware. He logrado esto antes sin modificaciones de PBC simplemente incrementando las tapas de desacoplamiento e interrumpiendo el apagón.

2) ¡Como ha señalado, el problema con FRAM es el precio!

3) Dependiendo de la volatilidad de sus datos de temperatura y posición, aumentará la resistencia escribiendo solo si el valor ha cambiado. Es posible que esté muestreando la temperatura una vez por segundo, pero si solo cambia cada 5 minutos, el problema se resuelve.

    
respondido por el Tim
1

Aquí es cómo resolví este problema en mi proyecto:

Reserve 1 sector de flash para contener una máscara de bits de ranuras no utilizadas y varias ranuras para el valor.

La máscara de bits que utilicé tenía 16 bytes de longitud, por lo que tenía 128 ranuras para poner valores.

La máscara de bits se inicializa en todas las unidades, que en términos de flash es el estado borrado.

Cuando quieras escribir un nuevo valor, lee la máscara de bits y encuentra el primer bit que es uno. Este es el número de ranura donde escribirá el valor. Cambie ese bit a cero para marcarlo como usado y vuelva a escribir la máscara de bits en flash sin borrarlo primero. A continuación, escriba el valor en la ranura después de la máscara de bits también sin borrar el flash.

De esta manera, extiende los ciclos de escritura flash 128 veces escribiendo la nueva máscara de bits con solo un cambio de uno a cero.

Si toda la máscara de bits es 0, borre el sector flash y comience de nuevo.

    
respondido por el Robert

Lea otras preguntas en las etiquetas