PEx IntFlashLdd1_Write with byte-wide values is overwriting adjacent bytes.

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

PEx IntFlashLdd1_Write with byte-wide values is overwriting adjacent bytes.

Jump to solution
1,551 Views
mstroven
Contributor III

Hello all,

I ran into this issue over the weekend.  I am using the FRDM-KE06Z dev board with KDS 3.0.

I have dedicated (4)  512-byte blocks of flash at Address 0x0000F800 for use as non-volatile data storage.

I am using the Processor-Expert-generated FLASH1_SetByteFlash( ) method to write 0s to a byte in my region.

The flash peripheral is setup using "write method" = "write" in PEx.

I apologize in advance for the length of the posting, but I want to avoid all of the typical "back-and-forth" and put out all the details at once.

Earlier code has already written the 0xfffffffd value at 0x0000F810 using the FLASH1_SetLongFlash method - which is working fine.

0x0000F800  FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

I am careful to only change ones to zeros.

As I step through the following code in the debugger, I see Bytes being modified at 0x0000F801, 0x0000F802, and 0x0000F803 as well.

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xFE );

verylongdelay();

At this point in the Memory Browser view, I see what I expect:

(Displaying in Little Endian format)

0x0000F800  FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

But watch after this is executed...

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xFC );

verylongdelay();

Now things have gotten weird:

0x0000F800  FFFFFEFC FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  üþÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

The new value is in the correct location, but the previously-written byte has moved up!

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xF8 );

verylongdelay();

0x0000F800  FFFEFCF8 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  øüþÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

Now again, the new write is correct, but the side effects are very annoying:

The two previously-written bytes have been flashed at the two addresses above my target writeaddress:

And so it continues with this write:

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xF0 );

verylongdelay();

0x0000F800  FEFCF8F0 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  ðøüþÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

Again.  Preview bytes are overwritten in higher-order bytes of the longword.

Now things change when we write again the 5th time.

We never go out of this specific long, but we do put the correct data at the correct target address:

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xE0 );

verylongdelay();

0x0000F800  FCF8F0E0 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  àðøüÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

Notice that no other bytes are affected when writing the 5th time.

But, as before, the three additional writes seem to adversely affect the other bytes in the longword:

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xC0 );

verylongdelay();

0x0000F800  F8F0E0C0 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  Àðøüÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0x80 );

verylongdelay();

0x0000F800  F0E0C080 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  .Àðøÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0x00 );

verylongdelay();

0x0000F800  E0C08000 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF  ..Ààÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ

Obviously, at this point we have zeroed all 8 bits at location 0x0000F800, so the experiment has to end.

Can someone else please verify this operation?  I am not sure whether this is a bug in the Processor Expert-generated code, or an issue with the Flash peripheral in the KE06Z part?

In order to keep moving forward with my project, I have replaced all FLASH1_SetByteFlash() calls with FLASH1_SetLongFlash(), and re-architected as necessary to use longwords instead of bytes.  Hopefully I can save others some hassle in the future...

Thank you,

-Mike

1 Solution
902 Views
BlackNight
NXP Employee
NXP Employee

Hi Mike,

from what is described here, this looks like a Processor Expert bug in the IntFlash component. I will file a ticket about it.

Erich

View solution in original post

8 Replies
902 Views
mjbcswitzerland
Specialist V

Mike

You cannot modify a long word once any bits in it have been set to 0.

This is a standard characteristic of the Flash used in all Kinetis parts (although some can't modify within an 8 bit phrase) and is clearly indiated in all user manuals:

pastedImage_0.png

The effect that you are seeing is probably due to EEC operation (although I don't know for sure since there is no documentation on the internal workings) whereby each write entity is saved with an EEC value (not visible but also in flash) when it is programmed which can correct an error (allowing smaller flash structures with lower reliability but offset by error correction). When the long word is changed it is no longer possible to change the EEC that was saved the first time and now when the Flash entity is read the EEC tries to correct bit(s) that no longer match and so you read back wierd values.

When the same incorrect utilisation of Flash takes place on some of the larger devices (like K70) the effect is that the read back phase causes a hardware access error (rather than just strange values) which is only corrected when an erase of the sFlash sector is performed.

Regards

Mark

Kinetis: µTasker Kinetis support

KE: µTasker FRDM-KE02Z support  / µTasker FRDM-KE02Z40M support  / µTasker FRDM-KE06Z support

For the complete "out-of-the-box" Kinetis experience and faster time to market

902 Views
mstroven
Contributor III

Thank you Mark,

This makes some sense to me.  It would indeed be very helpful to know what Freescale have actually implemented in the low-level Flash Controller...

That said, I was under the impression from the Processor Expert config help that the "write method" = "write", would disable this type of error checking.

Here is the help info that comes up:

Screen Shot 2015-06-17 at 11.12.17 AM.png

Apparently there is more going on below than I first assumed.

It is curious that the 32-bit long-writes are working exactly as I assumed the byte-writes would have.

If there are any freescale engineers on the board who can point me (us) to a more in-depth description of the flash controller implementation, I would greatly appreciate it.

(Thanks again Mark!)

Thanks in advance,

-Mike

0 Kudos
902 Views
mjbcswitzerland
Specialist V

Mike

There is in fact no such thing as a byte write for the Kinetis.

A byte write in a SW interface will only be positioning the byte accordingly in the long word and writing the long word with the other bytes set to 0xff. It still can't physically write more than one byte in a long word of Flash (in the KE part).

Regards

Mark

Kinetis: µTasker Kinetis support

KE: µTasker FRDM-KE02Z support  / µTasker FRDM-KE02Z40M support  / µTasker FRDM-KE06Z support

For the complete "out-of-the-box" Kinetis experience and faster time to market

902 Views
mstroven
Contributor III

It this is the case, then the PEx library code implementing the FLASH1_SetByteFlash() is faulty.  Since using the same scenario with FLASH1_SetLongFlash() seems to work exactly as expected....

0 Kudos
903 Views
BlackNight
NXP Employee
NXP Employee

Hi Mike,

from what is described here, this looks like a Processor Expert bug in the IntFlash component. I will file a ticket about it.

Erich

902 Views
mstroven
Contributor III

Erich,

Thank you for having a look.  I really appreciate it.

-Mike

0 Kudos
902 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

hi Mike,

To investigate your problem correctly and efficiently, please provide your demo project, I will check it directly on my side.

thanks!


Have a great day,
Zhang Jun

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
902 Views
mstroven
Contributor III

Hello Zhang Jun,

No project is necessary.  To verify, I started with a new Processor Export project on the FRDM-KE06Z dev board.

In PEx, instantiate the "IntFLASH" module and name it as FLASH1

export and compile your code.

Then in main(), you can just single step through the following code:

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xFE );

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xFC );

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xF8 );

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xF0 );

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xE0 );

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0xC0 );

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0x80 );

FLASH1_SetByteFlash(  (RecordStore_TAddress)0x0000F800, 0x00 );

At each step, in the Eclipse Memory Browser view, you can see the results of the write.

(Displaying in Little Endian format)

0x0000F800  FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF

I think that Mark Butcher has put me on the right track (see reply below), but it would be very helpful if someone from Freescale could point us to a more in-depth treatise on the Kinetis Internal Flash Controller...

Thanks,

-Mike

0 Kudos