I've tried to do flash logger function for my device based on STM32f407 and found some problem with flash:
If I uncomment function for clear sector, after load program my dummy data on first page is cleared before i start.
what I've done :
1) In .ld file I've define some sections:
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) in code create two const data arrays:
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)for test reason there was defined some data in header :
#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) and there is functions:
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;
}
and where it is called:
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 {
// both page is full clear first and mark as active scanPage = NextSectionPage(scanPage); // LOGSECONDPAGE to LOGFIRSTPAGE FLASHClear (scanPage); page = (FLASHSectionPage)scanPage; } } return page; }
5) call of second function is like these:
page = FLASHLog_ActivePageSrch( sectors, LOGDATACOUNT * 0x4 , 0x4 );
6) sector is constatn array - map of 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
};
And so, if i've comment this line FLASH->CR |= FLASH_CR_STRT;
after compile and debug I can see in memory in address 0x08008000 and 0x0800c000
DEADBEEF DEADBEEF
but if I just uncomment it and start debug there will be these data:
0x08008000 > FFFFFFFF FFFFFFFF
0x0800c000 > DEADBEEF DEADBEEF
Please help me to understand how is code for cleare page is done before I start, and how can I fix it