Correct way to deal with runtime error when running FTFE commands on K70

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Correct way to deal with runtime error when running FTFE commands on K70

764 Views
rahulfromdenobi
Contributor I
We are using the MK70FN1M0VMJ15 chip for our product. To implement a program flash upgrade mechanism, we use FTFE module commands to upgrade the flash. The function runs entirely from Ram, as recommended. It works for the most part. But, we are facing a lot of cases where the upgrade leaves the device unusable. This is probably due to the upgrade failing mid process, and device left with incomplete image.
 
The existing process looks something like this (simplified for clarity, original code takes care of boundary conditions):
 
//Function running from flash
 
void upgrade_flash(*flash_array, length)
 
{
 
//Wait for flash to be ready
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
 
//Erase the flash
FTFE_FCCOB0 = 0x44;
FTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
 
address = 0;
while(length > 0) {
 
//Read 8 bytes from flash_array at a time, run command to write the bytes to flash
FCCOB0 = 0x7
 
//Load address (64 bit alligned) onto FCCOB1, FCCOB2, FCCOB3;
 
//Load 8 bytes of data onto FCCOB4 to FCCOBB
 
FTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
 
length -=8
address += 8
flash_array += 8
}
 
REBOOT device.
 
}
 
 
 
Clearly, there is a problem here. There is no error flag checking. So, even if one of the above command fails, the rest of the flash
will stay erased causing the device to be unusable.
 
 
I am trying to implement error checking and possible corrections here to fix the issues.
 
 
I am attempting to change it to something like this:
 
void upgrade_flash(*flash_array, length)
 
{
 
//Wait for flash to be ready
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
if (FTFE_FSTAT & (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK))
        FTFE_FSTAT |= (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK);
 
//Erase the flash
while(1) {
FTFE_FCCOB0 = 0x44;
FTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
if (FTFE_FSTAT & (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK))
FTFE_FSTAT |= (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK);
if (!(FTFE_FSTAT & FTFE_FSTAT_MGSTAT0_MASK))
break;
}
 
 
address = 0;
while(length > 0) {
 
while (1) {
 
 //Read 8 bytes from flash_array at a time, run command to write the bytes to flash
FCCOB0 = 0x7
 
Load address (64 bit alligned) onto FCCOB1, FCCOB2, FCCOB3;
 
Load 8 bytes of data onto FCCOB4 to FCCOBB
 
FTFE_FSTAT |= FTFE_FSTAT_CCIF_MASK;
while (!(FTFE_FSTAT & FTFE_FSTAT_CCIF_MASK)) {}
if (FTFE_FSTAT & (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK))
FTFE_FSTAT |= (FTFE_FSTAT_ACCERR_MASK | FTFE_FSTAT_FPVIOL_MASK);
if (!(FTFE_FSTAT & FTFE_FSTAT_MGSTAT0_MASK))
break;
}
 
length -=8
address += 8
flash_array += 8
}
 
REBOOT device.
 
}

 

My main concern is, what is the correct way to handle runtime errors reported by MGSTAT0 bit? My new approach is just attempting to re run the command if it occurs. But, the documentation says that we cannot reprogram the same addresses without erase. But there is no command to erase just 8 bytes. Does that mean that we need to erase the complete block and start over again? Also, does checking the 3 error flags guarantee that the data was programmed correctly? Or should I read 1's and 0's using the block read commands at the end or programming the complete flash.

My goal is to make a failure proof procedure. Execution time is not that big a concern. A few minutes of program time is expected. Accuracy is more important, so that device can be upgraded without fear of corruption.

 

Labels (1)
0 Kudos
3 Replies

687 Views
bobpaddock
Senior Contributor III

To my knowledge, based on past NXP comments, full or block erase are the only option, byte/word level is not.

746 Views
bobpaddock
Senior Contributor III

"But there is no command to erase just 8 bytes. Does that mean that we need to erase the complete block and start over again?"

Yes.  I've been warned about just erasing a few bytes in the past.  It seems to have to do with wear leveling.

"Or should I read 1's and 0's using the block read commands at the end or programming the complete flash."

Yes, however, reading back flash right after it is written, not just these devices, is no guarantee of long term viability.  Flash works with floating gate charges.  A fresh write recharges the gate.  It tells nothing about the viability or degradation of the gate over time.  It may hold its charge for minutes or decades.
Something that reads fine at room temperature may fail to read at a higher temperature etc.

If you part has CRC ability in hardware that may be a faster option. That does not solve the gate charge issue.

Rereading does solve your immediate problem of did the product get programmed successfully.

If this issue is happening often, I'd look for things like questionable power supplies or reset circuits.




707 Views
rahulfromdenobi
Contributor I
Hi @bobpaddock, thanks for the response.
The MK70 reference manual does mention some internal verify mechanism, but I am not sure whether that is CRC based or not. From what I understand, reading data or "Program Check" which verifies 4 bytes a time does look like the only other way to check whether the data got programmed correctly.

What I am not sure is whether erasing the complete flash (or at least the block) is the only way to deal with an error if it arises.
0 Kudos