Checksum calculation

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to implement a checksum calculation into my code - something that can be queried after programming (and not embedded into the last location).

// Calculates program checksum
unsigned int calcChecksum(void)
{
	// Memory variables
	unsigned int memSum = 0;
	unsigned long memCnt = 0;

	// Sum all locations
	while (memCnt <= FLASHEND)
	{
		memSum += pgm_read_byte_far(memCnt++);
	}

	return memSum;

}  //  End of calcChecksum function

If I calculate the checksum of the produced .hex file it matches what is calculated provided I change:

FLASHEND

to the last location in the .hex file. I should note that I am using an ATmega2560. If I sum to the end of flash memory, it doesn't match as I believe the unused locations are set to 'FF'. I tried using code from some of these posts:

https://www.avrfreaks.net/index.p...

https://www.avrfreaks.net/index.p...

https://www.avrfreaks.net/index.p...

https://www.avrfreaks.net/index.p...

but I am confused. If I read the 32bit dword at 0x000000E4 (which is same as _VECTORS_SIZE by the way), I always get 0xE230BE1F - this does not change and exceeds the 0x0003FFFF program space. What am I doing wrong? Am I missing a setting or is there a way to write '00' to the unused locations instead of 'FF'?

I was also wondering if there is a way to retrieve all of the fuse settings from within my code and come up with a checksum for those.

-Thanks-

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which C commpiler? If GCC then look in the documentation (assuming WinAVR) for "Srecord". It will pad the unused parts of your .hex with any chosen value (0xFF is a good choice) and it will calculate and embed a checksum/CRC into the data. As long as your bootloader implements the same polynomial then this is all you need.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson-
Thanks for the quick reply. I forgot to mention that I am using WinAVR (but not using a bootloader though - was just looking for ideas). I will take a look at the documentation for that after lunch. Can I assume that the end programmed memory location is also part of that?

Any thoughts on generating a checksum for the fuses?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just Dl'd the sRecord pdf - is this a part of the default WinAVR (I assume not part of AVR Studio)? Can this be something that automatically builds when I hit 'F7'?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

is this a part of the default WinAVR

Yes you wasted your time downloading the PDF when it was already on your hard drive in:

c:\WinAVR(???)\doc\srecord

And the utilities are already there:

c:\WinAVR-20100110\bin>dir sre*
 Volume in drive C is ACER
 Volume Serial Number is C6B0-75D7

 Directory of c:\WinAVR-20100110\bin

19/01/2010  18:09           704,000 srec_cat.exe
19/01/2010  18:09           540,160 srec_cmp.exe
19/01/2010  18:09           540,672 srec_info.exe
               3 File(s)      1,784,832 bytes

It's srec_cat you will use with "filters".

BTW if not using a bootloader then what is the point of checksumming the code? If it's wrong then what? Also what's going to independently check the code image or are you suggesting a crc routine within the partly corrupt code image (which could include the CRC routine itself) is going to check itself? How if it is corrupt? (in which case calculating checksums is the least of your problems).

So I simply don't see the point of checksumming the code if it's not going to be done by an independent app that itself is protected and that can take action to remedy the situation.

Or is this one of these ridiculous design specs for "safety concious" equipment that says the says the code must be checksummed and regular checks be made on SRAM etc? (but to what effect? - the thing is fubar if they fail!)

If you are not programming by bootloader then I presume you are programming by ISP or JTAG? The read-verify phase they can do at the end of programming is surely at least as secure as a self checksum? Or is this going into space where the flash may be changed after it's been programmed by cosmic rays?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson-
Thanks again for the insight. I am programming via ISP. I agree with most of your statements but 'there has to be a way to identify what is fielded' according to our requirements. I thought a checksum would be the easiest as the ATmega2560 communicates with a ethernet/serial bridge. I am more a hardware/systems guy than software so I am not as familiar with all the features. I read through the document but was wondering - is srec_cat something that I need to do as a post-build thing or is it something I incorporate into the linker options or a makefile? Would you have an example to point me in the right direction?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do something like:

const char ver[] = "Program version "__DATE__" "__TIME__"\r\n";

then even if you extract an image and just load it into a hex editor you can spot this easily recognisable text somewhere. Even better might be to prefix it with "@(#)" so that a "what" utility will automatically pull the string out of a .bin copy.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does the "__DATE__" and "__TIME__" insert automatically via the build/compile or is it a manual entry?

Getting back to one of my original questions, how do I determine what the last programmed entry is?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Does the "__DATE__" and "__TIME__" insert automatically via the build/compile or is it a manual entry?

Yes they are set by the compiler at the time of compilation so each time you compile the file it will have a new value in this string automatically.

As for the end of the code. See a .map file:

 .fini0         0x00000cc8        0x4 c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a(_exit.o)
 *(.fini0)
                0x00000ccc                _etext = .

and then:

.data           0x00800100        0x4 load address 0x00000ccc

Finally followed by:

 *fill*         0x00800103        0x1 00
                0x00800104                _edata = .
                0x00800104                PROVIDE (__data_end, .)

So _etext is 0xCCC and the data initialisers are between 0x800100 and 0x800104. So there are 4 bytes in .data and therefore in flash the code will end at 0xCCC plus 4 which is 0xCD0. You can see this in the .hex:

:0C0CC000841F951FA01D0895F894FFCF1D
:040CCC002566000099
:00000001FF

The first line is the code 0xCC0 to 0xCCC and the next is the data at 0xCC0 to 0xCCF then the last line is the termination record.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys,
I am using AT90CAN128 for my project. Actually i wanted to know that is it possible to read the checksum of already programmed Flash using AVRStudio 4.
Kindly reply asap..

Regards,
Hrdish

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

is it possible to read the checksum of already programmed Flash using AVRStudio 4

Not directly. If the chip is not locked you can read the flash contents out to some .hex file and then run some kind of utility on that file to produce a checksum - maybe doing a hex2bin first.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

is it possible to read the checksum of already programmed Flash using AVRStudio 4

Not directly. If the chip is not locked you can read the flash contents out to some .hex file and then run some kind of utility on that file to produce a checksum - maybe doing a hex2bin first.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hey thanks for the reply...
i am able to read the checksum thru a software utility provided by AVRStudio4 named FLIP when a .hex file is passed to it but when i read from the programmed device and then pass it to flip it says "address out of range". Is there any limit to the size being read??

Do u know any other solution to read the checksum directly thru the programmed device??
pls reply...

Regards
Hrdish

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Like I say I'd use a DOS/Windows/Linux utility that can calculate data checksums, either use one that can read Intel .hex directly or first hex2bin the data.