0

So I'm trying to figure out a way to calculate a CRC with srec_cat before putting the code on a microcontroller. Right now, my post-build script uses the ielftool from IAR to do the calculation and insert it into the correct spot in the hex file.

I'm wondering how I can produce the same CRC with srec_cat, using the same hex file of course.

Here is the ielftool command that produces the CRC32 that I want to replicate:

--checksum APP_SYS_ApplicationCrc:4,crc32:1mi,0xffffffff;0x08060000-0x081fffff

  • APP_SYS_ApplactionCrc is the symbol where the checksum will be stored with a 4 byte offset added
  • crc32is the algorithm
  • 1 specifies one’s complement
  • m reverses the input bytes and the final checksum
  • i initializes the checksum value with the start value
  • 0xffffffff is the start value
  • And finally, 0x08060000-0x081fffff is the memory range for which the checksum will be calculated

I've tried a lot of things, but this, I think, is the closest I've gotten to the same command so far with srec_cat:

-crop 0x08060000 0x081ffffc -Bit_Reverse -crc32_b_e 0x081ffffc -CCITT -Bit_Reverse

  • -crop 0x08060000 0x081ffffc In a way specifies the memory range for which the CRC will be calculated
  • -Bit_Reverse should do the same thing as m in the ielftool when put in the right spot
  • -crc32_b_e is the algorithm. (I'm not sure yet if I need big endian _b_e or little endian _l_e)
  • 0x081ffffc is the location in memory to place the CRC
  • -CCITT The initial seed (start value in ielftool) is all one bits (it's the default, but I figured I'd throw it in there)

Does anyone have ideas of how I can replicate the ielftool's CRC? Or am I just trying in vain?

I'm new to CRCs and don't know much more than the basics. Does it even matter anyway if I have exactly the same algorithm? Won't the CRC still work when I put the code on a board?

Note: I'm currently using ielftool 10.8.3.1326 and srec_cat 1.63

Scott Madeux
  • 329
  • 3
  • 8
  • One thing that stands out is that your memory ranges are different. One ends with `ff` and other with `fc`. – user694733 Sep 17 '21 at 10:34
  • *"Does it even matter anyway if I have exactly the same algorithm?"* Depends on what you use the CRC for. None of the microcontrollers I have used have required any checksum; it's been typically added for non-technical reasons (like to satisfy certification requirement for example). – user694733 Sep 17 '21 at 10:37
  • I'd thought the same thing about the memory ranges and it's on my list of things to play around with. I was thinking though since the area where the CRC is supposed to be placed is initialized to be all zeros, that shouldn't have an effect on the CRC calculation right? – Scott Madeux Sep 17 '21 at 11:26
  • The microcontroller that this code is going on uses a bootloader that verifies the CRC. – Scott Madeux Sep 17 '21 at 11:34
  • *"...is initialized to be all zeros, that shouldn't have an effect on the CRC calculation right?"* No, I don't think that is right, if I remember correctly. It's a bit silly that your calculation includes these 4 bytes to checksum in the first place, but if it was there, then it needs to be there to get the same result. – user694733 Sep 17 '21 at 12:11
  • *"The microcontroller that this code is going on uses a bootloader that verifies the CRC."* Then both, generator and verfier, must have exactly same algorithm. How else would they get same result? – user694733 Sep 17 '21 at 12:12
  • 1
    Can you provide two examples using a small amount of data, same data on both systems (e.g. the nine bytes "123456789"), and the resulting CRCs from ielttool and srec_cat? – Mark Adler Sep 17 '21 at 17:31
  • @MarkAdler Do you have any ideas of how one might go about calculating the CRCs this way with ielftool or srec_cat? I've been trying to figure out how, for a while now and I'm not getting anywhere with it. – Scott Madeux Sep 20 '21 at 08:24
  • So I just noticed this output from the ielftool: _"Calculated the checksum for 0x81ffffc (APP_SYS_ApplicationCrc): 0xd8992b3d, the checksummed addresses were: 0x8060000 - 0x81ffffb (0x19fffc bytes)"_. I also found this in the srec_cat reference manual talking about the `-crop` option: _"The lower bound for all address ranges is inclusive, the upper bound is exclusive."_ This leads me to believe that both tools are in fact using the same memory range to compute the CRC `0x08060000-0x081ffffb` . – Scott Madeux Sep 20 '21 at 12:44
  • @ScottMadeux See my request in the comment just above yours. – Mark Adler Sep 20 '21 at 18:16
  • @MarkAdler Sorry I should have been more clear. I was wondering you had any idea how to get a CRC from either one of these tools using a small amount of data like "123456789". I can get it just fine if I have a whole program with everything mapped to memory addresses and an address to place the CRC, but I can't figure out for the life of me how to do it with something like a simple unsigned int. – Scott Madeux Sep 22 '21 at 06:08
  • I can't answer your question until you do what I asked, which is provide CRCs on example data. You don't want "a" CRC. You want to replicate a _specific_ CRC, which in your case can only be deduced from examples. If you don't want to do what I asked, then I cannot help you. The only way you can know that you are not getting the same CRC is by computing it on the same example data. If that is not what you're doing, then your question is not presenting the facts. – Mark Adler Sep 22 '21 at 15:16
  • @MarkAdler Thanks for being patient with me. What I'm trying to say is that **I can't figure out how to do what you asked in your first comment**. I would love to be able to calculate the CRCs on some small example data so I can better compare the CRCs that I get from each tool. I've been trying for days without success and **I was wondering if you had any suggestions on how I would be able to do what you had asked**. – Scott Madeux Sep 22 '21 at 15:25
  • Then how do you know you are not producing the same CRC with `srec_cat`, which is what your question says? Are you not able to get `srec_cat` to produce anything at all? Are you able to get `ielftool` to produce anything at all? – Mark Adler Sep 22 '21 at 17:03

1 Answers1

2

After many days of trying to figure out how to get the CRCs from each tool to match (and to make sure I was giving both tools the same data), I finally found a solution.

Based on Mark Adler's comment above I was trying to figure out how to get the CRC of a small amount of data such as an unsigned int. I finally had a lightbulb moment this morning and I realized that I simply needed to put a uint32_t with the value 123456789 in the code for the project I was already work on. Then I would place the variable at a specific location in memory using:

#pragma location=0x08060188
__root const uint32_t CRC_Data_Test = 123456789; //IAR specific pragma and keyword

This way I knew the variable location and length so could then tell the ielftool and srec_cat to only calculate the CRC over the area of that variable in memory.

I then took the elf file from the compiled project and created an intel hex file, so I could more easily look and make sure the correct variable data was at the correct address.

Next I sent the elf file through ielftool with this command:

ielftool proj.elf --checksum APP_SYS_ApplicationCrc:4,crc32:1mi,0xffffffff;0x08060188-0x0806018b proj.elf

And I sent the hex file through srec_cat with this command:

srec_cat proj.hex -intel -crop 0x08060188 0x0806018c -crc32_b_e 0x081ffffc -o proj_srec.hex -intel

After converting the elf with the CRC to a hex file and comparing two hex files I saw that the CRCs were very similar. The only difference was the endianness. Changing -crc32_b_e to -crc32_l_e got both tools to give me 9E 6C DF 18 as the CRC.

I then changed the memory address ranges for the CRC calculation to what they originally were (see the question) and I once again got the same CRC with both ielftool and srec_cat.

Scott Madeux
  • 329
  • 3
  • 8