Calculating a CRC16 and placing it in an SRecord file.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Calculating a CRC16 and placing it in an SRecord file.

8,408 Views
MTBer
Contributor I
Does anyone know if its possible to tell the compiler or linker to calculate a 16-bit CRC using polonomial 0xA001 over multiple pages (banked addresses) or a few ranges of addresses (global addresses) and placing the bytes in reverse order at a specific address.
 
I have tried to using the CHECKSUM method via the linker parameter (prm) file, but it seems that it can only perform the calculation on one section and then have to place the CRC at the location specified by the INTO section and not byte reversed.
 
I am using a HCS12XE device with Codewarrior 4.6.  Not sure what more information is needed, but please ask if you need more info.
 
Help would be greatly appreciated as I would prefer getting the compiler/linker doing this for me instead of having to write yet another tool to do this.
 
Thanks in advance for your response,
MTBer
Labels (1)
Tags (1)
0 Kudos
9 Replies

1,544 Views
J2MEJediMaster
Specialist I
Try reading this thread first. If that doesn't help, try entering "calculate checksum" in the search box at the bottom of this page and you'll get a display of several threads on the subject that might be of help.

---Tom
0 Kudos

1,544 Views
MTBer
Contributor I
Hi Tom,
 
Thanks for the reply.  I have actually done exactly that.  I was hoping that by now there has been some progress on this issue.  I have read through all the threads I could find and realize that there is a definite need for this functionality.
 
The problem is that I too wrote "quick" utilities to generate CRCs and insert them in the SRecord files, but these were very specific to the project that I worked on and also for the CPU and memory sizes etc.  To make it (more) generic will mean quite a bit more work and since a lot of the information and functionality is already from the compiler/linker, it would have made sense if it was fully implemented by the linker.
 
Anyway, the answer is that it is not possible.
 
I saw that it was (possibly) however requested.  Do you know whether there were any movements on this feature?
 
Thanks,
MTBer
0 Kudos

1,544 Views
CompilerGuru
NXP Employee
NXP Employee
This topic pretty much is the same as in this thread
http://forums.freescale.com/freescale/board/message?board.id=CW816COMM&message.id=3088

Still wondering what is the use case of a single CRC as opposed to having multiple ones for the multiple areas. In the end the runtime code has to compute the CRC over the areas anyway, so there has to be a list of all the areas. Why not just store the CRC as part of that data structure containing the addresses of the areas?

For the 3088 thread the answer was simple "it's a customer requirement".

Daniel

0 Kudos

1,544 Views
Lundin
Senior Contributor IV
Everything is possible. Why not allocate 2 bytes in flash/eeprom for a checksum variable, then write a PC program that goes through the .s19 file, translates everything useful to binary and calculates a checksum. Then it replaces the s-record where the flash checksum variable is located with the calculated value. And then let your program use that checksum when it calculates the flash.

You can then run your own program automatically from CW Edit->Settings->Target->Target Settings->Post-linker.
0 Kudos

1,544 Views
CompilerGuru
NXP Employee
NXP Employee
Just a little implementation remark. The batch burner does support to emit binary files, so the parsing of the srecord is not even needed, although its not that difficult either, of course.

Daniel
0 Kudos

1,544 Views
MTBer
Contributor I
Firstly, thanks a lot for your answers!  Its much appreciated!
 
@Lundin,
 
Your'e 100% correct.  Everyting is possible.  Its normally the amount of time you have that's an issue.  Like I said, we (used to) do exactly that (accept for automatically launching the tool).  All I am saying is that it would be nice if the tool could go all the way and implement what I can see a few people is already interested.  Its very close anyway.  I'm not sure why globals are not supported though.
 
Like I also said, that I wrote a tool that was very project specific and once the CPU memory changed, or our projects memory layout changes, we had to modify it.  So we tried not to modify anything unless we had to and we changed CPUs when we had to.  To make the tools generic would take a bit more time.
 
 
@Daniel,
 
The reason for using a single CRC used to be simpicity.  One CRC to calculate and check.  It is also a backward (I hate this word, it always brings out the worst in everything) compatibility issue.  Then we also have many tools used by our factory, customers and remote access tools etc.  And then finally, it was specified like this.  Unfortunately, it is just going to cause too many issues and maybe if I knew about CHECKSUM capability before I could have investigated whether we could use it, but we are very near to the end of the project now and the rest of the team is going to hang me if I even consider doing this.
 
I have also had a little brainwave last week.  Let me know if I am pulling at straws.
 
What if I calculate the checksum on one area and place it in the next.  Then continue on the next area and place next CRC in the next area and so on, until at the end. 
 
I need to obviously keep the CRC placement areas free, so it can be placed there.  I also need to sacrifice 2 bytes for every area, but this is OK.
 
Don't know if it will work yet.  Still busy coding/testing, but will hopefully make some time today to test it.
 
MTBer
0 Kudos

1,544 Views
MTBer
Contributor I
I have now tried using this CRC generation and feel that I have wasted enough time on it.  It just does not work for me.  Will have to write yet another utility to do this.  What a pity!
 
I must admit that I am very confused by it.  Not sure what it is doing.  I have the following test setup:
 
CHECKSUM
  CHECKSUM_ENTRY    METHOD_CRC16
    INIT    0
    POLY    0x8005
    OF      READ_ONLY   0x4002 TO 0x4003
    INTO    READ_ONLY   0x4000 SIZE 2
    UNDEFINED 0xff
  END
END

The data at the addresses 0x4002 to 0x4003 is 0x50 and 031.  The CRC calculated is 0xE0A0.  I can safely say that I cannot find anything that will generate the same CRC.  My existing CRC code, Hex Workshop and the many websites with calculators on them gives me: 0xD4FD.  So I am at a loss as to why the prm file generates this CRC.
 
I also thought about it accessing the incorrect data somehow, so I tested it with METHOD_CRC_CCITT and this gave me the correct result, so it must be using the correct data.
 
One more thing that puzzles me is why you cannot have an uneven amount of data.  Like one (3, 5, 7,...) byte(s).  That's not illegal, yet I get "Error: L1018: Checksum error size of checksum area not aligned with checksum size".  What is that about?
 
Anyway, like I said, it does not work for me.
 
Also, why does this site not warn you that it is going to time out or has timed out, so that you don't waste your time writing this whole thing and then come back just to loose it all.  I had to rewrite all this.  AGAIN!
 
MTBer.
0 Kudos

1,544 Views
PKZ
Contributor III

Hi,

 

I am having the same issue.

 

The CRC16 value (using 1021) generated by PRM file is different from that generated using code (from the library, C:\Program Files\Freescale\CodeWarrior for Microcontrollers V6.2\lib\hc08c\src\checksum.c).

0 Kudos

1,544 Views
sebbyBaby
Contributor II

Hi...

This may be a bit late for you now, but I also

had the same problem when I was using the IAR

linker on a project.

Apart from different polynomial values, the algorithm

used to calculate the CRC also varies... 

Envisage the CRC calculation as a serial bitstream of

data going into the LSB of a 16-bit CRC register, which

is occasionally XORed with the generating polynomial,

then:

CCITT algorithm will do the XOR if bit 15 of the CRC register

is different from the data bit being shifted in...

Other algorithm will always shift the data bit in, and will do the

XOR if bit 15 of the CRC register is 1....

 

There are other algorithms around (e.g.  MODBUS algorithm

is very different from what I've described above!), BUT I suspect

that the linker will revert to using the CCITT algorithm if the polynomial

chosen is 1021 (with initial value of 0xFFFF), and use the second

algorithm above  for all other cases.

[As if this weren't confusing enough, the CCITT algorithm also prepends

two NULs to the data stream... efectively changing the initial value from

$FFFF to $1D0F... this is definitely worth remembering.]

Hope this helps

 

 

 

 

 

0 Kudos