He intentado realizar la función de registrador de flash para mi dispositivo basado en STM32f407 y encontré algún problema con el flash:
Si desactivo la función para borrar el sector, después de cargar el programa, mis datos ficticios en la primera página se borran antes de que comience.
lo que he hecho:
1) En el archivo .ld he definido algunas secciones:
MEMORY
{
FLASH_S0 (rx) : ORIGIN = 0x08000000, LENGTH = 16K
FLASH_S1 (rx) : ORIGIN = 0x08004000, LENGTH = 16K /* Reserved for OS*/
FLASH_S2 (rx) : ORIGIN = 0x08008000, LENGTH = 16K /* LogPage1 */
FLASH_S3 (rx) : ORIGIN = 0x0800C000, LENGTH = 16K /* LogPage2 */
...
in SECTIONS :
.logPage1 :
{
. = ALIGN(4);
KEEP(*(.logPage1)) /*Startup code */
. = ALIGN(4);
} >FLASH_S2
.logPage2 :
{
. = ALIGN(4);
KEEP(*(.logPage2)) /* Startup code */
. = ALIGN(4);
} >FLASH_S3
2) en el código, crear dos matrices de datos const:
volatile const uint32_t __attribute__((section (".logPage1"))) log_data_page1[2] = {0xDEADBEEF, 0xDEADBEEF};
volatile const uint32_t __attribute__((section (".logPage2"))) log_data_page2[2] = {0xDEADBEEF, 0xDEADBEEF};
3) por razones de prueba, se definieron algunos datos en el encabezado:
#define LOGPAGENUM 2
#define LOGDATACOUNT 2
#define LOGDATASIZE FLASHLogDataSize_32b
#define FLASHPAGESIZE 0x4000
#define FLASHSTARTADDR 0x08000000
#define LOGFIRSTPAGE 2
#define LOGSECONDPAGE 3
#define SECTORCOUNT 12
4) y hay funciones:
BOOL FLASHClear (uint8_t clearSector){
FLASH_Status status;
if(clearSector >= SECTORCOUNT) return FALSE;
FLASH_Unlock();
while(FLASH->SR & FLASH_SR_BSY) {}
{
uint32_t Temp = FLASH->CR;
Temp &= ~(0xFUL << 3); // FLASH_CR_SNB [3:6]
Temp |= (clearSector << 3);
Temp |= FLASH_CR_SER;
FLASH->CR = Temp;
}
FLASH->CR |= FLASH_CR_STRT;
while(FLASH->SR & FLASH_SR_BSY) {}
FLASH->CR &= ~FLASH_CR_SER;
FLASH_Lock();
return status;
}
y donde se llama:
FLASHSectionPage FLASHLog_ActivePageSrch(TFLASHSector sectors[], uint32_t pageSize, uint8_t dataSize){
FLASHSectionPage page = FLASHSection_Page_None;
uint32_t headData ;
uint32_t tailData ;
uint8_t scanPage = (uint8_t) page;
// no While for less memory and CPU usage
scanPage = NextSectionPage(scanPage); // FLASHSection_Page_None в LOGFIRSTPAGE
headData = FLASHRead(sectors[scanPage].From);
tailData = FLASHRead(sectors[scanPage].From+ pageSize - dataSize);
if ( ((headData & EMPTYWORD) != EMPTYWORD) &&
((tailData & EMPTYWORD) == EMPTYWORD) ){
page = (FLASHSectionPage)scanPage;
}
else {
scanPage = NextSectionPage(scanPage); // LOGFIRSTPAGE в LOGSECONDPAGE
headData = FLASHRead(sectors[scanPage].From);
tailData = FLASHRead(sectors[scanPage].From+ pageSize - dataSize);
if ( ((headData & EMPTYWORD) != EMPTYWORD) &&
((tailData & EMPTYWORD) == EMPTYWORD) ){
page = (FLASHSectionPage)scanPage;
}
else {
// ambas páginas están completas primero, borra y marca como activa scanPage = NextSectionPage (scanPage); // LOGSECONDPAGE a LOGFIRSTPAGE FLASHClear (scanPage); page = (FLASHSectionPage) scanPage; } } página de retorno }
5) la llamada de la segunda función es como esta:
page = FLASHLog_ActivePageSrch( sectors, LOGDATACOUNT * 0x4 , 0x4 );
6) el sector es la matriz de constataciones - mapa de MCU flash: TFLASHLogMap FLASHLog;
static const TFLASHSector sectors[] = {
// STM32F40x, STM32F41x, STM32F42x, STM32F43x
{ 0x08000000UL, 0x08003FFFUL, 0 }, // 16 kB
{ 0x08004000UL, 0x08007FFFUL, 1 }, // 16 kB
{ 0x08008000UL, 0x0800BFFFUL, 2 }, // 16 kB
{ 0x0800C000UL, 0x0800FFFFUL, 3 }, // 16 kB
{ 0x08010000UL, 0x0801FFFFUL, 4 }, // 64 kB
{ 0x08020000UL, 0x0803FFFFUL, 5 }, // 128 kB
{ 0x08040000UL, 0x0805FFFFUL, 6 }, // 128 kB
{ 0x08060000UL, 0x0807FFFFUL, 7 }, // 128 kB
{ 0x08080000UL, 0x0809FFFFUL, 8 }, // 128 kB
{ 0x080A0000UL, 0x080BFFFFUL, 9 }, // 128 kB
{ 0x080C0000UL, 0x080DFFFFUL, 10 }, // 128 kB
{ 0x080E0000UL, 0x080FFFFFUL, 11 }, // 128 kB
};
Y así, si he comentado esta línea FLASH->CR |= FLASH_CR_STRT;
después de compilar y depurar puedo ver en la memoria en las direcciones 0x08008000 y 0x0800c000
DEADBEEF DEADBEEF
pero si simplemente lo descomprimo y empiezo a depurar habrá estos datos:
0x08008000 > FFFFFFFF FFFFFFFF
0x0800c000 > DEADBEEF DEADBEEF
Por favor, ayúdame a entender cómo se realiza el código para la página de borrado antes de comenzar, y cómo puedo solucionarlo