
alex m
Quiero escribir una variable, por ejemplo, un número entero con el número 5 en el FLASH y luego, después de que se apague y el dispositivo se encienda nuevamente, léalo.
Ya sé que para escribir algo primero necesito borrar la página y luego escribir.
En el manual dice:
- Escriba OPTKEY1 = 0x0819 2A3B en el registro de clave de opción Flash (FLASH_OPTKEYR)
- Escriba OPTKEY2 = 0x4C5D 6E7F en el registro de clave de opción Flash (FLASH_OPTKEYR)
¿Cómo realizo estas tareas?
El sector 0 tiene una dirección de bloque de 0x0800 0000 a 0x0800 3FFF, aquí es donde quiero escribir.
Aquí el enlace al manual, página 71: Manual STM32
Puede usar el siguiente código para escribir datos en flash con la biblioteca HAL.
void Write_Flash(uint8_t data)
{
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
FLASH_Erase_Sector(FLASH_SECTOR_6, VOLTAGE_RANGE_3);
HAL_FLASH_Program(TYPEPROGRAM_WORD, FlashAddress, data);
HAL_FLASH_Lock();
}
Debe actualizar el script del enlazador de la siguiente manera. Agregar DATA
en MEMORY
y añadir .user_data
en SECTIONS
.
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
DATA (rwx) : ORIGIN = 0x08040000, LENGTH = 128k
}
/* Define output sections */
SECTIONS
{
.user_data :
{
. = ALIGN(4);
KEEP(*(.user_data))
. = ALIGN(4);
} > DATA
Debe agregar el siguiente atributo en el código principal para leer datos después de encender
__attribute__((__section__(".user_data"))) const char userConfig[64];
Después de todo esto, puede leer sus datos flash llamando userConfig[0]
.

Esteban
Estoy usando STM32F407 y Atollic TrueSTUDIO® para STM32 versión 9.3.0.
Al usar el código sugerido anteriormente
atributo((sección(“.user_data”))) const char userConfig[64];
mi compilador asumió userConfig
ser cero constante. Tuve que quitar el const
de la declaración para que funcione.
Mi solución completa consta de dos partes (como ya se dijo anteriormente, pero con algunas modificaciones adicionales):
Paso 1 edite el archivo del enlazador:
En memoria’
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 896K /* origin size was 1024k, subtracted size of DATA */
DATA (rx) : ORIGIN = 0x080E0000, LENGTH = 128K
En ‘SECCIONES’
/* User data section at the end of the flash to store calibration data etc. */
.user_data (NOLOAD):
{
. = ALIGN(4);
_user_data_start = .; /* create a global symbol at user_data start */
KEEP(*(.user_data))
. = ALIGN(4);
_user_data_end = .; /* create a global symbol at user_data end */
} >DATA
Paso 2 escribir código:
uint8_t userConfig[64] __attribute__ ((section(".user_data")));
extern uint32_t _user_data_start;
extern uint32_t _user_data_end;
uint8_t ConfArray[16];
uint32_t TestArray[2];
// Copy a part from the userConfig to variable in RAM
for (i = 0; i < 16; i++)
{
ConfArray[i] = userConfig[i];
}
// get the address of start and end of user_data in flash
// the & is importand, else you would get the value at the address _user_data_start and _user_data_end points to
TestArray[0] = (uint32_t)&_user_data_start;
TestArray[1] = (uint32_t)&_user_data_end;
Depende mucho del hardware. Algunos tipos de memoria flash no permiten operaciones sin bloques en absoluto.
– 0andriy
08/06/2017 a las 20:10
@ 4386427 Eso es incorrecto.
OPTKEY1
yOPTKEY2
son valores, no direcciones. Agregarlos a la dirección de FLASH_OPTKEYR provocará un bloqueo o un comportamiento inesperado.– usuario149341
30 de junio de 2017 a las 23:18
@duskwuff – Ya veo. Lo leí como si OPTKEY1 y OPTKEY2 fueran dos registros dentro de un grupo de registros llamado FLASH_OPTKEYR. Comentario borrado. Gracias.
– Apoya a Ucrania
1 de julio de 2017 a las 6:07
Por supuesto, leer el manual en profundidad es una opción, pero generalmente también hay una nota de la aplicación sobre cómo se hace esto. Verifique las notas de la aplicación “emulación de eeprom” o “cargador de arranque”.
– Lundin
5 de septiembre de 2017 a las 9:57
Me gustaría señalar que la memoria flash solo tiene un número limitado de ciclos de escritura y borrado antes de degradarse. Recomiendo enfáticamente usar NVRAM respaldada por batería o alguna memoria no volátil externa de alta resistencia, por ejemplo, MRAM, para almacenar datos no volátiles que cambian con frecuencia. Personalmente, siempre voy con MRAM para esas cosas.
– datenwolf
30 de julio de 2020 a las 10:08