Reply by robm...@... March 28, 20052005-03-28

> And Rob, I believe you get 65280 more combinations! (65536-256) :-)

touche'


Reply by robm...@... March 28, 20052005-03-28
Well, yes, if as you say only a single byte is wrong and there are no
endian considerations then a checksum is adequate. If two bytes go wrong
in just the right way then the checksum is useless. Crc16 can be likewise
spoofed (with difficulty) and thus the need for SHA1, etc. with secure
stuff. Personally I feel that crc16 is overkill except for integrity
checks on large binaries. A RFID driver that I worked with recently used
crc16 for small transactions which was complete overkill.



Reply by Nigel Johnson March 28, 20052005-03-28
I have a very good paper calle "A Painless Guide to CRC error detection
algoritihms", whi I got from

ftp://ftp.rocksoft.com/papers/crc/crc_v3.txt

However, it doesn't seem to be there right now. If you like, I can see
if I have a machine-readable copy somewhere.

And Rob, I believe you get 65280 more combinations! (65536-256) :-)

but there I go splitting hairs again!
cheers,
Nigel
BobGardner@BobG... wrote:

>
>In a message dated 3/28/05 12:13:08 P.M. Eastern Standard Time,
>robmilne@robm... writes:
>
>Being a stickler here... >
>>To calculate the CRC...
>>
>>
>
>This is not a crc but a checksum with only 255 possible values (an lrc
>does the same trick with xor rather than addition).
>
>Crc is 16 bit with 2^8 more combinations. C implementation is simple and
>on the web.
>
>-Rob Milne >
>
>======================
>Hi Rob. Isnt a checksum just as good as a crc in applications where multiple
>bit errors and byte swapping dont occur? In other words, if you add up a
>dozen bytes and swap 2 of em, you get the same checksum, but not the same crc.
>That would be bad for typing in a lat/long for example, but reading a byte back
> from rom would be detected by the checksum calc no prob, right? >
>
>Yahoo! Groups Links >
>


--
Nigel Johnson
MCSE, MIEEE
VE3ID/G4AJQ

http://nigel.homelinux.net

If time travel ever will be possible, it already is. Ask me again yesterday


Reply by BobG...@... March 28, 20052005-03-28

In a message dated 3/28/05 12:13:08 P.M. Eastern Standard Time,
robmilne@robm... writes:

Being a stickler here...

> To calculate the CRC...

This is not a crc but a checksum with only 255 possible values (an lrc
does the same trick with xor rather than addition).

Crc is 16 bit with 2^8 more combinations. C implementation is simple and
on the web.

-Rob Milne

======================
Hi Rob. Isnt a checksum just as good as a crc in applications where multiple
bit errors and byte swapping dont occur? In other words, if you add up a
dozen bytes and swap 2 of em, you get the same checksum, but not the same crc.
That would be bad for typing in a lat/long for example, but reading a byte back
from rom would be detected by the checksum calc no prob, right?


Reply by robm...@... March 28, 20052005-03-28
Being a stickler here...

> To calculate the CRC...

This is not a crc but a checksum with only 255 possible values (an lrc
does the same trick with xor rather than addition).

Crc is 16 bit with 2^8 more combinations. C implementation is simple and
on the web.

-Rob Milne



Reply by Mark Wyman March 28, 20052005-03-28
I wanted to add one more thing in light of what others are suggesting:

Declare your structure as follows:
struct fileRecord{
unsigned char year;
unsigned int counts;
unsigned int electric_cost;

unsigned char crc;
} fileRecord;
And that will allow you to save the cyclic redundancy check value as the
last value written to the EEPROM during a record update. To calculate the
CRC, simply access your record as bytes:
sruct fileRecord myRecord;

unsigned char *pCharMyRecord;

short I;
myRecord.crc = 0;

pCharMyRecord = (unsigned char *)&myRecord;

for(I = 0; I < sizeof(fileRecord) - 1; I++) //Don't include the
CRC byte in the calculation

{

myRecord.crc += pCharMyRecord[i];

}
myRecord.crc = !myRecord.crc; //Invert data (prevents the case of all
zeros failure).

//Now write the data.
Perform the same calculation when you have read the data from the EEPROM and
see if the CRC read is the same as that calculated.
Now when you read data from the EEPROM, you can tell when the write went bad
by looking at the CRC vs. data the record contains. This will find a vast
majority of errors, but could potentially fail in the case of if the CRC
happens to match the erroneous data. This is a good start however, and is
more than enough if in a non-critical application. You can increase
reliability by increasing the CRC data size holder to two bytes so that the
value doesn't overflow, but in the interest of saving space, you can
truncate it to a single byte.
Another word of caution: Depending on what compiler you are using and what
options, it may force padding on elements in your structure. For example a
16-bit processor and compiler may allocate two bytes for "unsigned char
year" rather than just one byte to keep the data on even word boundaries.
The same may be true for CRC. You can easily check for this by sprintf() the
sizeof() the structure and see if agrees with what you calculate. If it
doesn't match, you will have to do things at the least common denominator of
size, say a word rather than a byte, or try a few other options.
-Mark Wyman
_____

From: robmilne@robm... [mailto:robmilne@robm...]
Sent: Saturday, March 26, 2005 9:54 PM
To: 68HC12@68HC...
Subject: RE: [68HC12] Re: Help needed storing array in EEPROM
Just to add to the previous.

The Pb of dysfunctional eeprom cells can only be solved by reading back
all of your writes (including the delete bitfield write for the crude
filesys).
Re-adjusting the linking pointers to bypass bad locations can be tricky if
the pointers themselves are faulty. Don't get too obsessed with faulty
memory if you aren't near the limits. Otherwise obsess with integrity
checks and redundancy schemes.

Rob Milne

<http://us.ard.yahoo.com/SIG98i4b5p/M)8184.6191685.7192823.3001176/D=gr
oups/S06554205:HM/EXP11978451/A%93423/R=0/SIGel9gslf/*http:/www.n
etflix.com/Default?mqso`190075> click here
<http://us.adserver.yahoo.com/l?M)8184.6191685.7192823.3001176/D=groups/S=
:HM/A%93423/rand8892665
_____

> Terms of Service.


Reply by robm...@... March 26, 20052005-03-26
Just to add to the previous.

The Pb of dysfunctional eeprom cells can only be solved by reading back
all of your writes (including the delete bitfield write for the crude
filesys).
Re-adjusting the linking pointers to bypass bad locations can be tricky if
the pointers themselves are faulty. Don't get too obsessed with faulty
memory if you aren't near the limits. Otherwise obsess with integrity
checks and redundancy schemes.

Rob Milne



Reply by robm...@... March 26, 20052005-03-26
>Don't ask me how I know all this because I'll just tell a fib..... 8-)

I won't look in the mouth. Good advice though. I need to start DP256
eeprom for the first time and I see that I will need to beef up my low
level driver.

The crude eeprom filesystem that I use is to is "label" your data
(collected into a "file" and given a name) and wrapped by a header with
size info that allows one to step along until a header with the right
"label" or filename match is made. The header can even contain a bitfield
that indicates active/erased status to somewhat improve an inefficient
scheme.

Wear leveling is effected by writing until the eeprom space is consumed
and then doing a defrag. Not code that you knock off in a day from
scratch and maybe not practical for some apps.

The real down and dirty method is to simply hardcode certain addresses for
specific variables with the smallest granularity possible (32 bit data).

Rob Milne



Reply by John Dammeyer March 26, 20052005-03-26
Hi,

The answer is yes, you can determine statically where you put the data.
However, writing out an entire year's worth of data each time is rather
inefficient. OTOH, writing out 25DECXX data once per second isn't the best
idea either.

Your algorithm that needs to store the data will decide how often you update
and you'll program that frequency based on EEROM life projected from the
data sheet.

It all depends on how much EEROM you have and how much data you want to
store and how often. All of those are project dependant values.

For example, if you are worried about EEROM cell failure then you could use
an index table to point to the data. Kind of like formating a directory on
a floppy drive disk. Create 366 pointer entries (16bit) that point to each
days record data. The data part is formed as an array of 500 records. Now
fill in the index table with the first 366 indexes to the records. (I'm
assuming fixed record size here).

Next calculate what day of the year 25DecXX is and index to that record. IF
the data in that record is corrupted because of EEROM failure change the
index value to point to a new free record from the list of 500. Since you
only write to the index table if an EEROM record fails, you won't exceed
the write cycles for that.

And, with a little bit of work you can test the entire algorithm on a PC.
Create a file the size of your EEROM with record sizes the size of your data
record. Initialize it to 500 empty records. Create a second file that is
your index table. Fill the first 366 locations with the #'s 1 to 365.

Now create the functions that will write out the data to the correct file
location based on the date. With minor tweaking and adding code to
read/write the EEROM instead of the disk drive, you'll have tested code that
works.

There are hundreds of solutions to your 'problem' Some are elequent and
others are clumsy or unreadable except to the original author.

All part of the fun.

John Dammeyer

>
> Basically, I never considered different approaches to storing
> data, beyond putting it into
> EEPROM. Thank you for that reasoning.
>
> The *problem* I have is this:
>
> If data for 12 (Dec), 25 is stored in a certain location in
> EEPROM, how do I know where that
> location is when I go to read the data? Do I have to loop
> through the EEPROM? Do I have to
> store the 12 and the 25 values?
>
> Originally, my plan for storing the struct array was just one
> month, so it was of size [31].
> However, I realized if I used the array as such: [12][31]
> then I could just reference the date
> above as array[12][25] (my previous email may have had this
> wrong) and capture the entire
> year. Once this worked out, I wanted to store the array for
> permanent storage.
>
> Here is the problem: Can I statically determine where each
> value will be put? If so, what
> happens if a memory location goes bad on the EEPROM? Or is
> that unlikely?
>
> And, if it is unlikely the data will go bad, I have a
> starting point with both of your
> responses, but am lacking some info still...
>




Reply by Simplymail March 26, 20052005-03-26

Combining both your responses, I'm going to reply...

Basically, I never considered different approaches to storing data, beyond putting it into
EEPROM. Thank you for that reasoning.

The *problem* I have is this:

If data for 12 (Dec), 25 is stored in a certain location in EEPROM, how do I know where that
location is when I go to read the data? Do I have to loop through the EEPROM? Do I have to
store the 12 and the 25 values?

Originally, my plan for storing the struct array was just one month, so it was of size [31].
However, I realized if I used the array as such: [12][31] then I could just reference the date
above as array[12][25] (my previous email may have had this wrong) and capture the entire
year. Once this worked out, I wanted to store the array for permanent storage.

Here is the problem: Can I statically determine where each value will be put? If so, what
happens if a memory location goes bad on the EEPROM? Or is that unlikely?

And, if it is unlikely the data will go bad, I have a starting point with both of your
responses, but am lacking some info still...