View previous topic :: View next topic |
Author |
Message |
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
#ID checksum and #ID checksum_program. |
Posted: Tue Oct 23, 2007 4:45 am |
|
|
Hi,
Anybody know the difference between these 2 ?
They give different results.
The older CCS EX_Checksum.c example program used #ID checksum_program and i used that i my code successfully.
But recently it stopped passing the checksum and i can't figure out why.
The newer version of EX_Checksum.c just uses #ID checksum but seems to use the same calculation (16 bit addition of all program memory) but still fails in my code.
A older version of my code compiled with the latest compiler works ok, it's just the newer code fails the checksum. The checksum code is unchanged between the versions.
I've tried CCS support but they seem to be having problems. i get confirmation messages back with a completly different title, or none at all.
Thanks,
Jim |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Oct 23, 2007 5:59 am |
|
|
It would really help when you mentioned the compiler versions. Also, the ex_checksum.c example is different for PIC16 and PIC18 processors, so what is your processor?
Without this information we can do nothing to verify your results.
Please note that the v4.0xx compiler is still considered a beta release. '#id checksum_program' is not in the manual and might have been a dropped feature in favour of the older '#id checksum' directive. |
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
|
Posted: Tue Oct 23, 2007 6:57 am |
|
|
Sorry, i'm using version V4.059 on a 18LF6722 but i did try several different compiler versions and my earlier version of the project still compiles and the checksum works with V4.059
CCS obviously don't consider V 4.0xx as beta even if it should be, and #ID checksum is in the manual and the example file so should be supported.
I used #ID checksum_program as that was what was in the example file for earlier versions of 4.0xx when i started the project, and it did still work until recently.
It was only when i found it no longer worked that i investigated and found
#ID checksum. But that gives a different result so i assume is calculated in a different way.
This is my cut down and modified version of the CCS example code.
Code: |
#id checksum_program
int1 perform_checksum()
{
int16 checksum, check_id;
int32 i;
int8 j;
checksum = 0; // Initialize the addition checksum to zero at start
check_id = 0; // Initialize variable to read ID location - only for PIC18
// The following code will return an additions checksum for entire program memory
for(i=0;i<getenv("Program_memory");i+=2)
{
checksum+=read_program_eeprom(i); // read 16 bits from program memory
}
// The following code will read the checksum stored using #ID checksum_program command
for(j=0;j<=3;j++)
check_id=check_id*16+(read_program_eeprom(0x200000+j*2) & 0x0f); // mask so only lower nibble is used.
if(check_id==checksum)
return 1;
else
return 0;
} |
Thanks.
Jim |
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
|
Posted: Tue Oct 23, 2007 8:29 am |
|
|
Oops, slight mistake in my earlier messages, all versions of the examples use #id checksum_program, it's the manual that mentions just #id checksum
Jim |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Oct 23, 2007 8:39 am |
|
|
Jim Hearne wrote: | Oops, slight mistake in my earlier messages, all versions of the examples use #id checksum_program, it's the manual that mentions just #id checksum | That's what I tried to say, '#id checksum_program' is an undocumented feature while '#id checksum' is documented. It would be interesting to know how both functions differ in the calculation of the checksum but this something you will have to ask CCS. |
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
|
Posted: Tue Oct 23, 2007 8:46 am |
|
|
#ID checksum_program is whats in the CCS example program though, there are no details in the manual (that i can find) that describe using #ID program.
I just got this from CCS.
Quote: | Just "checksum" includes the configuration words in the checksum. The "checksum_program" is just the program memory. |
I've now asked for more details on how it's calculated.
Thanks,
Jim |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Oct 23, 2007 9:02 am |
|
|
Sorry, where did you see '#id program'?
I know there was a feature request for making it possible to select how the checksum is calculated. You can put any value you want in the ID locations at memory address 0x200000 to 0x200007, for example a serial number. Some people want the checksum to only include program memory and others to include the ID locations as well.
Seems like CCS implemented this feature but forgot to update the manual. |
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
|
Posted: Tue Oct 23, 2007 9:06 am |
|
|
Sorry, not doing too well today.
The examples use #ID checksum_program, the manual only mentions #ID checksum (not #ID program).
Thanks,
Jim |
|
|
Jim Hearne
Joined: 22 Dec 2003 Posts: 109 Location: West Sussex, UK
|
Update: |
Posted: Fri Oct 26, 2007 6:07 am |
|
|
CCS have confirmed this seems to be a bug with the compiler not doing a checksum on all the memory.
A work around was moving a #ROM address from 0x0001e000 to 0x00010000 (18LF6722 with 128k rom).
Jim |
|
|
Zer0flag Guest
|
Re: Update: |
Posted: Thu Jan 03, 2008 3:30 pm |
|
|
Did you check this line in ex_checksum.c :
Code: |
for (i=0; i<getenv("PROGRAM_MEMORY"); i+=2)
|
In this sample prog the var i is declared as int16 and as far as I see this var cannot hold memory sizes of 64K and above, so it has to be redeclared as int32.
I also do not quite understand why it stores the checksum in an int16. Wouldn't it be better to have a int32 here also?
And I don't exactly understand how this works:
Code: |
for (i=0; i<=3; i++)
check_id=check_id*16+(read_program_eeprom(0x200000+i*2) & 15);
|
|
|
|
Zer0flag Guest
|
Re: Update: |
Posted: Thu Jan 03, 2008 5:19 pm |
|
|
Zer0flag wrote: |
And I don't exactly understand how this works:
Code: |
for (i=0; i<=3; i++)
check_id=check_id*16+(read_program_eeprom(0x200000+i*2) & 15);
|
|
Ahhh, I found the answer in another thread.
One can test this:
#ID 0xABCD
Shows in MPLAB as User ID:
A0B0C0D0
So the calculated #ID CHECKSUM is always a 16 bit number which is spread over 32 bit and there are zeros between the nibbles. This explains the function shown above which is from ex_checksum.c
|
|
|
|