Uso la biblioteca st eeprom para guardar mis variables. Cuando guardo una sola variable, no tengo ningún problema. Puedo guardarlo, actualizarlo y después de desconectar la alimentación, puedo leer esa variable. Ahora quiero guardar tres variables diferentes en tres páginas diferentes, cuando quiero leerlas, veo el último valor en todas ellas. Con este código guardo las variables:
HAL_FLASH_Unlock();
EE_Init();
EE_WriteVariable(VirtAddVarTab[0], 10);
EE_WriteVariable(VirtAddVarTab[1], 20);
EE_WriteVariable(VirtAddVarTab[2], 30);
HAL_Delay(10);
EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);
EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]);
EE_ReadVariable(VirtAddVarTab[2], &VarDataTab[2]);
HAL_FLASH_Lock();
Después de programar este código, programo este:
HAL_FLASH_Unlock();
EE_Init();
EE_ReadVariable(VirtAddVarTab[0], &VarDataTab[0]);
EE_ReadVariable(VirtAddVarTab[1], &VarDataTab[1]);
EE_ReadVariable(VirtAddVarTab[2], &VarDataTab[2]);
HAL_FLASH_Lock();
Y veo "30" en todos los de la memoria en lugar de 10,20,30 ¿Cuál es mi problema?
direcciones de pagina:
#define ADDR_FLASH_PAGE_0 ((uint32_t)0x08000800) /* Base @ of Page 0, 1 Kbytes *///0x08000000
#define ADDR_FLASH_PAGE_1 ((uint32_t)0x08001000) /* Base @ of Page 1, 1 Kbytes *///0x08000400
#define ADDR_FLASH_PAGE_2 ((uint32_t)0x08001800) /* Base @ of Page 2, 1 Kbytes *///0x08000800
#define ADDR_FLASH_PAGE_3 ((uint32_t)0x08002000) /* Base @ of Page 3, 1 Kbytes *///0x08000C00
#define ADDR_FLASH_PAGE_4 ((uint32_t)0x08002800) /* Base @ of Page 4, 1 Kbytes *///0x08001000
#define ADDR_FLASH_PAGE_5 ((uint32_t)0x08003000) /* Base @ of Page 5, 1 Kbytes *///0x08001400
#define ADDR_FLASH_PAGE_6 ((uint32_t)0x08003800) /* Base @ of Page 6, 1 Kbytes *///0x08001800
#define ADDR_FLASH_PAGE_7 ((uint32_t)0x08004000) /* Base @ of Page 7, 1 Kbytes *///0x08001C00
#define ADDR_FLASH_PAGE_8 ((uint32_t)0x08004800) /* Base @ of Page 8, 1 Kbytes *///0x08002000
#define ADDR_FLASH_PAGE_9 ((uint32_t)0x08005000) /* Base @ of Page 9, 1 Kbytes *///0x08002400
#define ADDR_FLASH_PAGE_10 ((uint32_t)0x08005800) /* Base @ of Page 10, 1 Kbytes *///0x08002800
Y tengo dos IROM IROM1 la dirección de inicio es 0x8000000 y su tamaño es 0x400 IROM2 la dirección de inicio es 0x8000800 y su tamaño es 0xF800
Los defino al principio del programa:
uint16_t VirtAddVarTab[20];
uint16_t VarDataTab[20];
No lo inicialicé. ¿Quiere decir que puse, por ejemplo, 0 al principio y luego los uso?
La biblioteca pseudo EEPROM de STM ofrece una interfaz para leer y escribir pares clave/valor. Las claves son uint16_t
valores. Se supone que la matriz VirtAddVarTab
contiene todas las claves posibles.
Su código no se inicializa explícitamente VirtAddVarTab
. Entonces, todas las claves son 0. Por lo tanto, el código siempre escribe y lee desde la clave 0.
Para solucionarlo, inicialice VirtAddVarTab
, por ejemplo:
uint16_t VirtAddVarTab[NB_OF_VAR] = { 0x100, 0x0102, 0x0200 };
Si bien VirtAddVarTab
es necesario, no necesita usarlo para EE_WriteVariable()
y EE_ReadVariable()
. (Supongo que lo ha copiado del extraño código de ejemplo de STM).
Un enfoque mejorado sería:
#define EE_KEY_COLOR 0x0100
#define EE_KEY_BRIGHTNESS 0x0102
#define EE_KEY_MODE 0x0200
uint16_t VirtAddVarTab[NB_OF_VAR] = { EE_KEY_COLOR, EE_KEY_BRIGHTNESS, EE_KEY_MODE };
uint16_t color;
uint16_t brightness;
uint16_t mode;
...
EE_ReadVariable(EE_KEY_COLOR, &color);
EE_ReadVariable(EE_KEY_BRIGHTNESS, &brightness);
EE_ReadVariable(EE_KEY_MODE , &mode);
VirtAddVarTab
se requiere cuando una página flash se ha llenado y los pares clave/valor activos deben transferirse a otra página flash. Es una decisión de diseño desafortunada por parte de STM, ya que genera una dependencia mutua entre el código del proyecto y el código de la biblioteca.
El enfoque de STM para la pseudo EEPROM es sólido: reduce el desgaste de la memoria flash y puede recuperarse incluso si falla la energía durante la escritura. Sin embargo, la API es más compleja de lo necesario y la documentación, aunque cubre la implementación en detalle, no describe suficientemente el uso.
codo
Hamed P.
codo
Hamed P.
brahans
VirtAddVarTab
matriz?Kartman
codo
VirtAddVarTab
se supone que contiene las llaves. Como no lo inicializa, todas las claves son 0. Por lo tanto, cualquier cosa que lea y escriba, siempre será hacia y desde la clave 0. Es por eso que obtiene 30 como resultado.codo
VirtAddVarTab
contener todas las claves. Es necesario transferir las entradas activas a una nueva página flash cuando la página está llena.brahans
Hamed P.
Hamed P.
Hamed P.