EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Saving data in CPU on-chip EEPROM

Started by yossi_sr June 14, 2005
On Fri, 17 Jun 2005 07:27:03 +1200, Jim Granville
<no.spam@designtools.co.nz> wrote:

>Anton Erasmus wrote: >>>One solution may be to use checksum on all block of data, and >>>always recalculate the new checksum after each parameter change.If >>>the checksum is not OK I can clear all parameters.I don't like this >>>solution because in case of one error I should clear all >>>the list of failures. >>>Is there any other solution or suggestion how to solve this problem? >> >> >> Use Gray Code for the counters. Only one bit changes between succesive >> counts, which of course means only one byte changes. Make sure that if >> there is a power failure, you have enough power to at least complete >> any write you are busy with. That way if power fails, you either have >> incremented the counter, or you have missed only one count. > > Sounds fine, but what actually happens in the EEPROM update process, >is the buried EE state engine first erases the byte (or page) and then >replaces it with the new value(s). > Some have Page schemes, but allow single byte replace - that just >means they ready the page, XOR it with the new info, and write the whole >page back. > Thus, even with Gray code, there are finite times, where you have >[OldValue][Erasing to 0FFH][0FFH][Writing NewValueZeroes][NewValue]
That is why I suggested that there must be enough capacitance to allow any write that has started to complete. Many external brownout detectors has a "power-fail" alarm pin that activates at a higher voltage than the reset. This pin can be used to make sure that a write is not started just before a power fail. [Snipped] Regards Anton Erasmus
On Thu, 16 Jun 2005 19:41:25 GMT, Jonathan Kirwan
<jkirwan@easystreet.com> wrote:

>On Thu, 16 Jun 2005 12:30:37 +0200, Anton Erasmus ><nobody@spam.prevent.net> wrote: > >><snip> >>Use Gray Code for the counters. Only one bit changes between succesive >>counts, which of course means only one byte changes. Make sure that if >>there is a power failure, you have enough power to at least complete >>any write you are busy with. That way if power fails, you either have >>incremented the counter, or you have missed only one count. >>I have used this method on an AVR that counts operation cycles on a >>unit. Of over 300 units that has been operating over the last 4 years, >>I have had no corrupt counters. > >I'm interested in the exact details of this. It is easy for me to >imagine how this might be done, using a routine to read a gray code >from non-volatile memory and convert it into multi-byte binary form in >RAM, where it is incremented., and then converted this result back to >gray code before writing back to non-volatile memory. > >But I don't know of a direct method to simply read out the current >gray code value and more directly figure out which byte may have >changed. It seems to me that the conversion to binary, with an >increment taking place in that domain, is necessary. > >The conversion back and forth is relatively easy, but one of the >conversions involves a loop and I'm wondering if there is a method >that does not involve a loop and could be used to operate in an >expression form.
Yes, what you have described is essentailly what I use. To ensure that I do not write too many times to the same location, I use multiple 16 bit counters which are all initialized to 0. I then increment the first counter until it has reached the maximum. I then start incrementing the second etc. To get the total count I add the value of all the counters. For the gray conversion I have not found a method that does not imply a loop. One can probably use some sort of lookup table based algorithm if the loop construct is a problem. Regards Anton Erasmus
Jonathan Kirwan wrote:
>
... snip on use of Gray counters ...
> > The conversion back and forth is relatively easy, but one of the > conversions involves a loop and I'm wondering if there is a method > that does not involve a loop and could be used to operate in an > expression form.
If all you want to do is increment, a transition table is easily created from a Karnaugh map. Once you see the sequence of the first four states, the second four is obvious, and thence the second eight, etc. It may be educational to map "complement bit n on next clock" for the first three bits. -- Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net) Available for consulting/temporary embedded and systems. <http://cbfalconer.home.att.net> USE worldnet address!
On 2005-06-17, CBFalconer <cbfalconer@yahoo.com> wrote:
> Jonathan Kirwan wrote: >> > ... snip on use of Gray counters ... >> >> The conversion back and forth is relatively easy, but one of >> the conversions involves a loop and I'm wondering if there is >> a method that does not involve a loop and could be used to >> operate in an expression form. > > If all you want to do is increment, a transition table is > easily created from a Karnaugh map. Once you see the sequence > of the first four states, the second four is obvious, and > thence the second eight, etc. It may be educational to map > "complement bit n on next clock" for the first three bits.
But, since you can't erase/program a single bit it's mostly moot. -- Grant Edwards grante Yow! Do you have exactly at what I want in a plaid visi.com poindexter bar bat??
Anton Erasmus wrote:
> On Fri, 17 Jun 2005 07:27:03 +1200, Jim Granville > <no.spam@designtools.co.nz> wrote: > > >>Anton Erasmus wrote: >> >>>>One solution may be to use checksum on all block of data, and >>>>always recalculate the new checksum after each parameter change.If >>>>the checksum is not OK I can clear all parameters.I don't like this >>>>solution because in case of one error I should clear all >>>>the list of failures. >>>>Is there any other solution or suggestion how to solve this problem? >>> >>> >>>Use Gray Code for the counters. Only one bit changes between succesive >>>counts, which of course means only one byte changes. Make sure that if >>>there is a power failure, you have enough power to at least complete >>>any write you are busy with. That way if power fails, you either have >>>incremented the counter, or you have missed only one count. >> >> Sounds fine, but what actually happens in the EEPROM update process, >>is the buried EE state engine first erases the byte (or page) and then >>replaces it with the new value(s). >> Some have Page schemes, but allow single byte replace - that just >>means they ready the page, XOR it with the new info, and write the whole >>page back. >> Thus, even with Gray code, there are finite times, where you have >>[OldValue][Erasing to 0FFH][0FFH][Writing NewValueZeroes][NewValue] > > > That is why I suggested that there must be enough capacitance to allow > any write that has started to complete. Many external brownout > detectors has a "power-fail" alarm pin that activates at a higher > voltage than the reset. This pin can be used to make sure that a write > is not started just before a power fail. > > [Snipped] >
Gray code here provides no possible benefit, since the data is not updated a bit at a time. Gray code is important when sampling multi-bit data in different clock domains (such as for absolute position encoders, or counters in FIFOs), but gives you little (avoiding the occasional write of the high byte of your 16-bit counter) for the extra headaches here. If your power-fail alarm and your capacitor charges are sufficient to ensure that power-fail will never stop in the middle of a write, then just store the counters directly. Of course, it relying on such a system would be risky if it is not clearly over-dimensioned, especially when there are such simple ways of ensuring reliability without it.
On Fri, 17 Jun 2005 02:07:29 -0000, Grant Edwards <grante@visi.com>
wrote:

>On 2005-06-17, CBFalconer <cbfalconer@yahoo.com> wrote: >> Jonathan Kirwan wrote: >>> >> ... snip on use of Gray counters ... >>> >>> The conversion back and forth is relatively easy, but one of >>> the conversions involves a loop and I'm wondering if there is >>> a method that does not involve a loop and could be used to >>> operate in an expression form. >> >> If all you want to do is increment, a transition table is >> easily created from a Karnaugh map. Once you see the sequence >> of the first four states, the second four is obvious, and >> thence the second eight, etc. It may be educational to map >> "complement bit n on next clock" for the first three bits. > >But, since you can't erase/program a single bit it's mostly >moot.
If only a single bit changes, it folows that only a single byte changes. Hence to increment a counter one only has to write one byte no matter how many bits the total counter is. To prevent corruption of the counter one have only to ensure that either the one byte write completes fully or is not performed at all. It is not to difficult to ensure that there is enough time from a "pending power fail" signal until the MCU is reset for an EEPROM write to complete. Regards Anton Erasmus
On Fri, 17 Jun 2005 09:30:29 +0200, David Brown
<david@westcontrol.removethisbit.com> wrote:

>Anton Erasmus wrote: >> On Fri, 17 Jun 2005 07:27:03 +1200, Jim Granville >> <no.spam@designtools.co.nz> wrote: >> >> >>>Anton Erasmus wrote: >>> >>>>>One solution may be to use checksum on all block of data, and >>>>>always recalculate the new checksum after each parameter change.If >>>>>the checksum is not OK I can clear all parameters.I don't like this >>>>>solution because in case of one error I should clear all >>>>>the list of failures. >>>>>Is there any other solution or suggestion how to solve this problem? >>>> >>>> >>>>Use Gray Code for the counters. Only one bit changes between succesive >>>>counts, which of course means only one byte changes. Make sure that if >>>>there is a power failure, you have enough power to at least complete >>>>any write you are busy with. That way if power fails, you either have >>>>incremented the counter, or you have missed only one count. >>> >>> Sounds fine, but what actually happens in the EEPROM update process, >>>is the buried EE state engine first erases the byte (or page) and then >>>replaces it with the new value(s). >>> Some have Page schemes, but allow single byte replace - that just >>>means they ready the page, XOR it with the new info, and write the whole >>>page back. >>> Thus, even with Gray code, there are finite times, where you have >>>[OldValue][Erasing to 0FFH][0FFH][Writing NewValueZeroes][NewValue] >> >> >> That is why I suggested that there must be enough capacitance to allow >> any write that has started to complete. Many external brownout >> detectors has a "power-fail" alarm pin that activates at a higher >> voltage than the reset. This pin can be used to make sure that a write >> is not started just before a power fail. >> >> [Snipped] >> > >Gray code here provides no possible benefit, since the data is not >updated a bit at a time. Gray code is important when sampling multi-bit >data in different clock domains (such as for absolute position encoders, >or counters in FIFOs), but gives you little (avoiding the occasional >write of the high byte of your 16-bit counter) for the extra headaches >here. If your power-fail alarm and your capacitor charges are >sufficient to ensure that power-fail will never stop in the middle of a >write, then just store the counters directly. Of course, it relying on >such a system would be risky if it is not clearly over-dimensioned, >especially when there are such simple ways of ensuring reliability >without it.
I disagree. Using gray code when incrementing/decrementing a counter in EEPROM ensures that one need to worry only about one byte at a time. (Only one bit changing implies that only one byte changes) One then only has to ensure that the EEPROM write is not started just before a power fail, and if the power fails just after a write has started, that there is enough reserve power for the one byte write to finish. Using the appropriate external browout detector, makes this simple and reliable. One can also put the Gray count value in the EEPROM such that one EEPROM byte represents a single bit. Again because only one bit changes, one has to worry only about updating one byte per count. Even if the underlying mechanism erases a page, and reprograms it, there is still a maximum time that it takes to do this, and one must just ensure that if a write has started, that the MCU stays alive for this time before going down. Regards Anton Erasmus
Anton Erasmus wrote:
> On Fri, 17 Jun 2005 09:30:29 +0200, David Brown > <david@westcontrol.removethisbit.com> wrote: > > >>Anton Erasmus wrote: >> >>>On Fri, 17 Jun 2005 07:27:03 +1200, Jim Granville >>><no.spam@designtools.co.nz> wrote: >>> >>> >>> >>>>Anton Erasmus wrote: >>>> >>>> >>>>>>One solution may be to use checksum on all block of data, and >>>>>>always recalculate the new checksum after each parameter change.If >>>>>>the checksum is not OK I can clear all parameters.I don't like this >>>>>>solution because in case of one error I should clear all >>>>>>the list of failures. >>>>>>Is there any other solution or suggestion how to solve this problem? >>>>> >>>>> >>>>>Use Gray Code for the counters. Only one bit changes between succesive >>>>>counts, which of course means only one byte changes. Make sure that if >>>>>there is a power failure, you have enough power to at least complete >>>>>any write you are busy with. That way if power fails, you either have >>>>>incremented the counter, or you have missed only one count. >>>> >>>>Sounds fine, but what actually happens in the EEPROM update process, >>>>is the buried EE state engine first erases the byte (or page) and then >>>>replaces it with the new value(s). >>>>Some have Page schemes, but allow single byte replace - that just >>>>means they ready the page, XOR it with the new info, and write the whole >>>>page back. >>>>Thus, even with Gray code, there are finite times, where you have >>>>[OldValue][Erasing to 0FFH][0FFH][Writing NewValueZeroes][NewValue] >>> >>> >>>That is why I suggested that there must be enough capacitance to allow >>>any write that has started to complete. Many external brownout >>>detectors has a "power-fail" alarm pin that activates at a higher >>>voltage than the reset. This pin can be used to make sure that a write >>>is not started just before a power fail. >>> >>>[Snipped] >>> >> >>Gray code here provides no possible benefit, since the data is not >>updated a bit at a time. Gray code is important when sampling multi-bit >>data in different clock domains (such as for absolute position encoders, >>or counters in FIFOs), but gives you little (avoiding the occasional >>write of the high byte of your 16-bit counter) for the extra headaches >>here. If your power-fail alarm and your capacitor charges are >>sufficient to ensure that power-fail will never stop in the middle of a >>write, then just store the counters directly. Of course, it relying on >>such a system would be risky if it is not clearly over-dimensioned, >>especially when there are such simple ways of ensuring reliability >>without it. > > > I disagree. Using gray code when incrementing/decrementing a counter > in EEPROM ensures that one need to worry only about one byte at a > time. (Only one bit changing implies that only one byte changes) One > then only has to ensure that the EEPROM write is not started just > before a power fail, and if the power fails just after a write has > started, that there is enough reserve power for the one byte write to > finish. Using the appropriate external browout detector, makes this > simple and reliable. > One can also put the Gray count value in the EEPROM such that one > EEPROM byte represents a single bit. Again because only one bit > changes, one has to worry only about updating one byte per count. > Even if the underlying mechanism erases a page, and reprograms it, > there is still a maximum time that it takes to do this, and one must > just ensure that if a write has started, that the MCU stays alive for > this time before going down. > > Regards > Anton Erasmus
If you can make your hardware safe for a single byte write, you can make it safe for a two byte write (or whatever length of counter you want), elimating the complexity of gray codes. I'd still avoid a system that relied on running after power has been turned off - journaling is easy to do if you think it through carefully, and far more flexible (for example, you can group a number of changes). If you have lots of eeprom space and want to spread your wear-and-tear evenly, that's perfectly possible too (add a version number to your data). mvh., David
On Fri, 17 Jun 2005 14:50:35 +0200, David Brown
<david@westcontrol.removethisbit.com> wrote:

>Anton Erasmus wrote: >> On Fri, 17 Jun 2005 09:30:29 +0200, David Brown >> <david@westcontrol.removethisbit.com> wrote: >> >> >>>Anton Erasmus wrote: >>> >>>>On Fri, 17 Jun 2005 07:27:03 +1200, Jim Granville >>>><no.spam@designtools.co.nz> wrote: >>>> >>>> >>>> >>>>>Anton Erasmus wrote: >>>>> >>>>> >>>>>>>One solution may be to use checksum on all block of data, and >>>>>>>always recalculate the new checksum after each parameter change.If >>>>>>>the checksum is not OK I can clear all parameters.I don't like this >>>>>>>solution because in case of one error I should clear all >>>>>>>the list of failures. >>>>>>>Is there any other solution or suggestion how to solve this problem? >>>>>> >>>>>> >>>>>>Use Gray Code for the counters. Only one bit changes between succesive >>>>>>counts, which of course means only one byte changes. Make sure that if >>>>>>there is a power failure, you have enough power to at least complete >>>>>>any write you are busy with. That way if power fails, you either have >>>>>>incremented the counter, or you have missed only one count. >>>>> >>>>>Sounds fine, but what actually happens in the EEPROM update process, >>>>>is the buried EE state engine first erases the byte (or page) and then >>>>>replaces it with the new value(s). >>>>>Some have Page schemes, but allow single byte replace - that just >>>>>means they ready the page, XOR it with the new info, and write the whole >>>>>page back. >>>>>Thus, even with Gray code, there are finite times, where you have >>>>>[OldValue][Erasing to 0FFH][0FFH][Writing NewValueZeroes][NewValue] >>>> >>>> >>>>That is why I suggested that there must be enough capacitance to allow >>>>any write that has started to complete. Many external brownout >>>>detectors has a "power-fail" alarm pin that activates at a higher >>>>voltage than the reset. This pin can be used to make sure that a write >>>>is not started just before a power fail. >>>> >>>>[Snipped] >>>> >>> >>>Gray code here provides no possible benefit, since the data is not >>>updated a bit at a time. Gray code is important when sampling multi-bit >>>data in different clock domains (such as for absolute position encoders, >>>or counters in FIFOs), but gives you little (avoiding the occasional >>>write of the high byte of your 16-bit counter) for the extra headaches >>>here. If your power-fail alarm and your capacitor charges are >>>sufficient to ensure that power-fail will never stop in the middle of a >>>write, then just store the counters directly. Of course, it relying on >>>such a system would be risky if it is not clearly over-dimensioned, >>>especially when there are such simple ways of ensuring reliability >>>without it. >> >> >> I disagree. Using gray code when incrementing/decrementing a counter >> in EEPROM ensures that one need to worry only about one byte at a >> time. (Only one bit changing implies that only one byte changes) One >> then only has to ensure that the EEPROM write is not started just >> before a power fail, and if the power fails just after a write has >> started, that there is enough reserve power for the one byte write to >> finish. Using the appropriate external browout detector, makes this >> simple and reliable. >> One can also put the Gray count value in the EEPROM such that one >> EEPROM byte represents a single bit. Again because only one bit >> changes, one has to worry only about updating one byte per count. >> Even if the underlying mechanism erases a page, and reprograms it, >> there is still a maximum time that it takes to do this, and one must >> just ensure that if a write has started, that the MCU stays alive for >> this time before going down. >> >> Regards >> Anton Erasmus > >If you can make your hardware safe for a single byte write, you can make >it safe for a two byte write (or whatever length of counter you want), >elimating the complexity of gray codes. I'd still avoid a system that >relied on running after power has been turned off - journaling is easy >to do if you think it through carefully, and far more flexible (for >example, you can group a number of changes). If you have lots of eeprom >space and want to spread your wear-and-tear evenly, that's perfectly >possible too (add a version number to your data).
The gray code method is only suitable for incrementing/decrementing a counter in EEPROM. If one wants to save other types of data reliably to EEPROM, then other methods such as you describe are in order. For just a counter the gray code method is simple and easy to code as well as reliable. Regards Anton Erasmus
On 2005-06-17, Anton Erasmus <nobody@spam.prevent.net> wrote:

[Regarding gray code]

>>But, since you can't erase/program a single bit it's mostly >>moot. > > If only a single bit changes, it folows that only a single byte > changes. Hence to increment a counter one only has to write one byte > no matter how many bits the total counter is. To prevent corruption of > the counter one have only to ensure that either the one byte write > completes fully or is not performed at all. It is not to difficult to > ensure that there is enough time from a "pending power fail" signal > until the MCU is reset for an EEPROM write to complete.
If all you ever need to save to EEPROM is counters, then I guess it could be useful. If, however, you have to save to EEPROM anything that's not a counter, then you've got to have a more general solution for atomic writes to EEPROM. -- Grant Edwards grante Yow! FEELINGS are at cascading over me!!! visi.com

Memfault Beyond the Launch