Auto Linker in IAR Embedded Workbench

I am working on a firmware project in which I have to do a crc16 check for flash integrity.

crc is calculated using the Xlink IAR linker and saved at the end of the flash. Again, crc is computed at runtime from the code and compared with the stored value in the flash to verify integrity. However, we can only compute crc on the flash code segment. Its size may change whenever we make some changes to the code. Can I automate this process, which I am doing now manually?

from the linker .xcl file:

// --------------------------------------------------------- // CRC16 Essentials: -H for fill,-J for checksum calculation // --------------------------------------------------------- -HFF -J2,crc16,,,CHECKSUM2,2=(CODE)5C00-FF7F;(CODE)10000-0x20A13 

Here I need to change the final value of the second code segment, which is 0x20A13 right now. I get this value from a .map file, i.e. From what range of memory my code is inside the flash. This is the first change I am making.

Here I need to make the 2nd change from the code:

  sum = fast_crc16(sum, 0x5C00, 0xFF7F-0x5C00+1); sum = fast_crc16(sum, 0x10000,0x20A13-0x10000+1); //Check the crc16 values if(sum != __checksum) { // Action to be taken if checksum doesn't match } 

Please help automate this process!

+4
source share
2 answers

You can try to use the built-in functions __segment_begin and __segment_size or __segment_end in the IAR, which are described in the "C / C ++ Compiler Reference Guide", which can be accessed from the Help menu in the EW430 IAR. The manual says that they work with segments defined in the linker file, and many people on the Internet seem to use it that way, but I tried and got compiler errors (IAR EW430 5.40.7). If this is somehow broken, you can report it to the IAR and get a fix (provided that you have a support contract).

You can use them as follows:

 sum = fast_crc16(sum, __segment_begin("CODE"), __segment_size("CODE")); 

I do not know what happens to split segments. But why would you exclude your reset vectors from your checksum calculation? You can simply go from the beginning of CODE to the end and enable the reset vectors.

I think you could structure your code like this:

 sum = fast_crc16(sum, __segment_begin("CODE"), (char *)__segment_begin("INTVEC") - (char *)__segment_begin("CODE") + 1); sum = fast_crc16(sum, 0x10000, (char *)__segment_end("CODE") - 0x10000); 

In addition, you may or may not have noticed that the __checksum variable is placed in memory wherever it fits. I found that it was hiding after my DATA16_ID segment, which put it right in the middle of the checksum code range, and I did not know how to automate skipping memory partitions to calculate the checksum. What I did was force __checksum for the first two bytes in the flash, defining a segment for these first two bytes and putting it there.

Edit: skipped the first change. If you manually adjust the range of the IAR linker checksum procedure to be able to use segment functions from the compiler, you will need to define a user segment that uses the end of your code in your linker.

I don't know if there is a way to automate this. You may need to compile your code twice (ugh) once with an unlimited segment to get the end of the code, then use a script to extract the end of the code, and then update the script linker. You can probably start the initial build in a command line event before build and just build an IAR project with an unlimited linker file. But that seems pretty ugly.

+2
source

Perhaps you can also change your mind to build crc on top of the full flash memory reserved for the application, and not just for the used part.

Then you do not need to change the linker file, not your c-code, and even the loader can calculate crc without knowing the actual size of the application.

+2
source

All Articles