Hi, everyone.
Recently, I encountered an issue with the product I'm currently working on. The product uses a piece of the flash memory to store the user's data. It is organized as a very primitive file system, where each "file" uses a page (512 bytes). The MCU is LPC5528 running at clock speed is 96 MHz.
At a certain moment a sample just refused to boot up. The review uncovered, that it was caused by the initialization failure, which comprises the creation of certain "files" and their population with data. More specifically, the "FLASH_VerifyProgram" function returned the code 117, which in the user manual is described as "kStatus_FLASH_CompareError" (see "Chapter 9 - Flash API")
The further study pointed to the byte 0x0007B6C2 to be in charge of the issue. Its expected value was 0x00 while in fact it was 0x02. The sequence used to write data is presented below.
#include <fsl_iap.h>
#include <fsl_iap_ffr.h>
flash_config_t flashInstance;
uint8_t flashBuffer[512];
uint8_t flashCheckBuffer[512];
void flashTest(void)
{
status_t result;
uint32_t failedAddress = ~0;
uint32_t failedData = ~0;
FLASH_Init(&flashInstance);
flashInstance.modeConfig.readSingleWord.readWithEccOff =
kFLASH_ReadWithEccOff;
memset(flashBuffer, 0, sizeof flashBuffer);
memset(flashCheckBuffer, 0, sizeof flashCheckBuffer);
/* The user's data region occupies the 0x0007B600 - 0x0007FFFF
region, 18.5 KBytes in total. */
result = FLASH_Erase(&flashInstance, 0x0007B600, 0x4A00,
kFLASH_ApiEraseKey);
if (result != kStatus_Success) {
while(1);
}
result = FLASH_Program(&flashInstance, 0x0007B600,
flashBuffer, sizeof flashBuffer);
if (result != kStatus_Success) {
while(1);
}
result = FLASH_VerifyProgram(&flashInstance, 0x0007B600,
sizeof flashBuffer, flashBuffer,
&failedAddress, &failedData);
if (result == kStatus_Success) {
while(1);
}
result = FLASH_Read(&flashInstance, 0x0007B600,
flashCheckBuffer, sizeof flashCheckBuffer);
if (result != kStatus_Success) {
while(1);
}
for (size_t byte = 0; byte < sizeof flashCheckBuffer; ++byte) {
if (flashBuffer[byte] != flashCheckBuffer[byte]) {
// Here the execution stops, because byte 0xC2 is not zero
while(1);
}
}
}
Above I'm completely erasing the user region and performing a test write to the first page. Despite the fact that the data is just all zeros, the byte 0x0007B6C2 obtains the 0x02 value. If I try to put the 0xA0 value there, the outcome will be 0xA2. It feels like a single bit is corrupted and swapped upon every program attempt.
My little questions:
- How common are cases like this? Considering a sample encountered no stresses like overvoltage/overheating, etc.
- Is it a permanent damage or it can be somehow tweaked by software? (Not likely, I know)
If the risk is significant, then more efforts must be put in to guarantee the integrity of the data.