View previous topic :: View next topic |
Author |
Message |
Tagge
Joined: 23 Aug 2005 Posts: 93
|
Flash checksum |
Posted: Tue Mar 20, 2007 5:04 am |
|
|
Hi, Im trying to certify that the program memory is ok at start up.
Im looking thru all posts at this forum, but Im not sure if anyone has got it working allright? I tryed all of the tips that i found, but nothing seems to work. Many of the topics has also gone out of date.
Im using a PIC18F2525 at 20MHz, compiler ver 3.242.
I tryed this solution that seems fine, but the calculated checksum isnt the same as the one generated?
Code: |
boolean check_flash(void)
{
#id CHECKSUM
int32 addrs=0;
int16 orig_cksum;
int16 cksum=0x0000;
int16 buf[64];
int32 addr_max=0xbfff;//Flash size -1
int8 i;
do{
read_program_memory(addrs, buf, 128);
for(i=0; i<64; i++)
cksum += buf[i];
addrs += 128;
} while (addrs <= addr_max);
cksum ^=0xffff;
cksum += 0x0001;
read_program_memory(0x00200006, &orig_cksum, 2);
if(orig_cksum != cksum)
return FALSE;
else
return TRUE;
} |
I would also like to make a check of some values written in to an external eeprom, at power fail. A small and very fast checksum? Anyone has an idea?
Thanks/ |
|
|
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
|
Posted: Tue Mar 20, 2007 5:43 am |
|
|
Seems like you have found my checksum generator in this forum. Please see that post again, I have made an update. Use the exact verification routine source code that the program now generates. It would be helpful if you give me some feedback about how it works for you. Good luck. |
|
|
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
|
Tagge
Joined: 23 Aug 2005 Posts: 93
|
|
Posted: Tue Mar 20, 2007 6:19 am |
|
|
Ok, but it seems to complaine about that the k values are missing in the database? Im doing something wrong, Im sure..
But can it use the checksum generated by the compiler?
#checksum
to match to? |
|
|
Tagge
Joined: 23 Aug 2005 Posts: 93
|
|
Posted: Tue Mar 20, 2007 6:28 am |
|
|
Hi Tom,
It doesnt give the same value as the #checksum?
Is there any modification to be done to a 18f2525?
Is it critical in wish part of the program this function is called?
Code: | boolean check_flash(void)
{
#id CHECKSUM
int32 Rom_address;
unsigned long romcheck = 0x0000, cs_temp;
// Calculate checksum of all program flash.
for (Rom_address = 0; Rom_address < getenv("PROGRAM_MEMORY"); Rom_address+=2){
cs_temp = read_program_eeprom(Rom_address);
romcheck += cs_temp;}
// Include all configuration words (as 16 bit numbers) into checksum.
for (Rom_address = 0x300000; Rom_address <= 0x30000D; Rom_address+=2){
cs_temp = read_program_eeprom(Rom_address);
romcheck += cs_temp;}
// Check if this is rhe first run of the code by checking for a checksum
if (read_program_eeprom(0x200000) == 0xFFFF){
write_program_eeprom(0x200000,romcheck);}
if (read_program_eeprom(0x200000) == romcheck){
return True;} // -- CheckSum is OK --
return(False); // CheckSum error
} |
|
|
|
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
|
Posted: Tue Mar 20, 2007 6:52 am |
|
|
Tagge wrote: | Ok, but it seems to complaine about that the k values are missing in the database? Im doing something wrong, Im sure..
But can it use the checksum generated by the compiler?
#checksum
to match to? |
There is no need to use the #ID Checksum provided by CCS. I have no idea how it is calculated, by the way. I use my own routine, that I can trust.
You should have a .bat file for compiling, that looks like this:
Code: | hcg18.exe -source -pci 18F2525 verify.c
"c:\picc\ccsc.exe" +FH main.c
hcg18.exe -cksum -pci 18F2525 main.hex main.hex
|
First line: the verification routine is generated and saved to the file verify.c.
Second line: the compiler is called to generate the hex file. This will have no checksum. The file main.c should include verify.c somewhere and should have a call like this one below somewhere as close to the beginning of the program as possible:
Code: | if (!firmware_ok()) {
lcd_putc(msgCorruptedFirmware);
while (TRUE) ;
} |
Third line: the generator is called again, it parses the hex file to calculate its checksum, and then puts it in the PIC's ID as the last two bytes. Now the failsafe main.hex is ready to be burned into the PIC.
Try to make a minor change in the final hex file (don't forget it's own end-of-line checksum!) and you will see that the check will fail once the program runs on the PIC.
Hope this helps you. |
|
|
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Tue Mar 20, 2007 9:40 am |
|
|
Tagge
My code from the old post did not use #ID CHECKSUM at all.
I concur with Mr. VanHauser and two or three people on this form.
We don't know how CCS calculates the CHECKSUM number.
++++++++++++++++++++++
This problem has been solved. See the following thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=58331
- Forum Moderator
++++++++++++++++++++++
You can find more on this topic by searching for ROM Check or #ID Checksum I think.
My function does not use #ID CHECKSUM so that line will need to be removed for my function to work.
All that my function does the first time it runs is add up all the program memory and the configuration words then write this value to ID Checksum location on the PIC.
The second time it just add up all the program memory and the configuration words then see if it equals the value stored at end ID location.
One thing that you need to check is that the ID address of 0x200000 is ok to use for your PIC.
Reread the old post then check your data sheet for your PIC for this info.
Tom |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Mar 20, 2007 11:14 am |
|
|
Quote: | I would also like to make a check of some values written in to an external eeprom, at power fail. A small and very fast checksum? Anyone has an idea? | Checksums based on a CRC algorithm are much better in detecting errors than algorithms based on addition but slightly slower. For relative short data checks (up to a few hundred values) I can recommend the Dallas 1-wire CRC-8 routine http://www.ccsinfo.com/forum/viewtopic.php?t=26264
Or use the CRC-16 routine from http://www.ccsinfo.com/forum/viewtopic.php?t=24977 which requires a similar computational effort but is much more secure. |
|
|
Tagge
Joined: 23 Aug 2005 Posts: 93
|
|
Posted: Wed Mar 21, 2007 1:06 am |
|
|
Thanks all, this is the best forum on the net!
Sorry to say that its also extremely needed with CCS
As the fact that nobody knows how they calculate the checksum, why isn't there a help on this! Its crucial to check the program at start up if you want to get a product certified, at least here in Sweden!
I still got problem with Toms code, is it because at testing and reprogramming you will change the checksum, and therefor it will be wrong..
Now i solved it, you must use the erase_memory_eeprom() function to "reset" the checksum! It cant be overwritten!
Here it is for someone else to use
Code: | void check_flash(void)
{
int32 Rom_address;
unsigned long romcheck = 0x0000, cs_temp;
//ERASE_PROGRAM_EEPROM(0x200000); // if you want to reset checksum
// Calculate checksum of all program flash.
for (Rom_address = 0; Rom_address < getenv("PROGRAM_MEMORY"); Rom_address+=2){
cs_temp = read_program_eeprom(Rom_address);
romcheck += cs_temp;}
// Include all configuration words (as 16 bit numbers) into checksum.
for (Rom_address = 0x300000; Rom_address <= 0x30000D; Rom_address+=2){
cs_temp = read_program_eeprom(Rom_address);
romcheck += cs_temp;}
// Check if this is rhe first run of the code by checking for a checksum
if (read_program_eeprom(0x200000) == 0xFFFF){
write_program_eeprom(0x200000, romcheck);}
if (read_program_eeprom(0x200000) == romcheck)
go = True; // -- CheckSum is OK --
else go = false; // CheckSum error
}
|
|
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
|
Posted: Wed Mar 21, 2007 2:43 am |
|
|
I've just added a program memory checksum to my code using the EX_checksum.c example that came with version 4.020 and it seems to work fine on a 18LF6722 once i'd changed the loop variable from 16 to 32 bit to handle the 128k rom.
I doubt i'm allowed to post CCS example code here but they use #id checksum_program to store the checksum in the ID and getenv("Program_memory") to determine the size of the program the checksum is over. |
|
|
|