I have reserved one flash page for saving an operating hours counter. There is an array of 32 entries in RAM of "unsinged long". This array is also filled with "0xFFFFFFFF". Every hour the index for the array is incremented by "1". After reaching the last entry, the index is set to "0" and the flash page will be erased. On the first run, the reserved flash page is cleared (every entry is 0xFFFFFFFF) and the array is also filled with 0xFFFFFFFF. After every hour, the complete array is copied into flash, without erasing. This shall work, because writing the same values or wriring the new last updated array entry value shall work. Sometimes this stategy fails and the stored data in flash is not the same as in the array. Why is it so? If I erase the flash page before write the new content of array, it works. But I don't want to erase the flash page every hour. My stategy is to ease it every 32 hours to save writing cycles.
Screenshot of memory content:
-sOPHours stored in RAM
-csOPHours stored in FLASH
The last new entry was 1077. During write RAM into FLASH, the entry of index 20 was set to an invalid value, Why?
and this is with erasing:
//prepare for sector erasing
ulCommand[0]=PREPARE_FLASH2WRITE;
ulCommand[1]=ucGetSector_Number((unsigned long)ulDest);
ulCommand[2]=ucGetSector_Number((unsigned long)(ulDest)+ulSize-1);
ulCommand[3]=SystemCoreClock / 1000;
iap_entry((unsigned int*)&ulCommand[0],(unsigned int*)&ulResult[0]);
//maybe test for errors
if (ulResult[0] != 0)
{
taskEXIT_CRITICAL();
return;
}
//erase sectors
ulCommand[0]=ERASESECTORS;
iap_entry((unsigned int*)&ulCommand[0],(unsigned int*)&ulResult[0]);
//maybe test for errors
if (ulResult[0] != 0)
{
taskEXIT_CRITICAL();
return;
}
//prepare for sector writing
ulCommand[0]=PREPARE_FLASH2WRITE;
ulCommand[1]=ucGetSector_Number((unsigned long)pDest);
ulCommand[2]=ucGetSector_Number((unsigned long)pDest+sizeof(ucBuffer)-1);
iap_entry((unsigned int*)&ulCommand[0],(unsigned int*)&ulResult[0]);
//maybe test for errors
if (ulResult[0] != 0)
{
taskEXIT_CRITICAL();
return;
}
ulCommand[0]=COPYRAM2FLASH;
ulCommand[1]=(unsigned long)pDest;
ulCommand[2]=(unsigned long)&ucBuffer[0];
ulCommand[3]= sizeof(ucBuffer)/4;
ulCommand[4]=SystemCoreClock / 1000;
iap_entry((unsigned int*)&ulCommand[0],(unsigned int*)&ulResult[0]);
//maybe test for errors
if (ulResult[0] != 0)
{
taskEXIT_CRITICAL();
return;
}
Here it is:
//prepare for sector writing
ulCommand[0]=PREPARE_FLASH2WRITE;
ulCommand[1]=ucGetSector_Number((unsigned long)pDest);
ulCommand[2]=ucGetSector_Number((unsigned long)pDest+sizeof(ucBuffer)-1);
iap_entry((unsigned int*)&ulCommand[0],(unsigned int*)&ulResult[0]);
//maybe test for errors
if (ulResult[0] != 0)
{
taskEXIT_CRITICAL();
return;
}
ulCommand[0]=COPYRAM2FLASH;
ulCommand[1]=(unsigned long)pDest;
ulCommand[2]=(unsigned long)&ucBuffer[0];
ulCommand[3]= sizeof(ucBuffer)/4;
ulCommand[4]=SystemCoreClock / 1000;
iap_entry((unsigned int*)&ulCommand[0],(unsigned int*)&ulResult[0]);
//maybe test for errors
if (ulResult[0] != 0)
{
taskEXIT_CRITICAL();
return;
}
ulResult[0] is always "0". SystemCoreClock is 100MHz.
Some comments.
Have you read section 5.2.2 of the user manual? There is an interesting comment about the flash accelerator maybe returning stale data if not using erase.
have you reserved the top 32 bytes of ram for the flash programmer? 32.3.2.7 in the user manual
I am not using the watchdog. Interruptes are disabled during erasing, writing and comparing. There is a reserved memory area of 32 bytes @ 0x10007FE0.
I have made a small statistic:
write accesses: 6539
store invalid data: 1896
The 2nd paragraph of 5.2.2 is the interesting bit - not the bit about watchdog. See below
have you verified that you get no errors if you perform the erase first? I.e. check that there is not another issue here.
In order to preclude the possibility of stale data being read from the flash memory, the LPC176x/5x flash accelerator buffers are automatically invalidated at the beginning of any flash programming or erase operation. Any subsequent read from a flash address will cause a new fetch to be initiated after the flash operation has completed.
Do you know any other work a round? Or shall I increase the flash wait states?
Every "result" after erasing or writing is "0".
Do you mean this at 5.2.2:"In order to preclude the possibility of stale data being read from the flash memory, the LPC176x/5x flash accelerator buffers are automatically invalidated at the beginning of any flash programming or erase operation. Any subsequent read from a flash address will cause a new fetch to be initiated after the flash operation has completed."
The content of flash is always invalid, after many readings. The case of invalid stored data is realy random.
Could you share your code for programming flash (with and without erase). You may be missing a step.