IELFTOOL Checksum - Placing the checksum

Technical Note 62709

Architectures:

ARM, RH850, RX, SH, STM8

Component:

general

Updated:

11/6/2015 10:22 AM

Introduction

Here follows the possibilities for placement of the checksum.

Place last in memory.

Covered in Technical Note 65473.

Placing it before the start of application code.

define block CHECKSUM { ro section .checksum };
place in ROM_region { ro, first block CHECKSUM };

In the example (made with IAR Embedded Workbench for ARM) project Example (1 range, 3 diff. locations).zip, use the configuration 'PlaceInFirstBlock' , the start address is 0x84 and the end address is 0xFFFF.

Note:

The start address is after the interrupt vector and after the checksum value, that is in this case, the checksum calculation does not include the interrupt vector (normally located at address 0x0 and placed with a specific 'place at' directive).

Placing it after the end of the application code.

define block CHECKSUM { ro section .checksum };
place in ROM_region { ro, last block CHECKSUM };

In the 'Example (1 range, 3 diff. locations)' (link above), configuration 'PlaceInLastBlock' , the start address is 0x0 and the end address is 0x296B. During development the actual application end address will vary from build to build, thus it will become cumbersome to change the end address often (as the checksum must be placed outside the memory which is checksummed). Recommended is to use this configuration in the release phase of the project. Note: To overcome this inconvenience, see the alternative solution using checksum-start and checksum-end markers.

The ordinary (one range) example

The 'Example (1 range, 3 diff. locations)' (link above), includes the actual generic C source to calculate the same checksum value as ielftool.exe produces in its CRC calculation. It also contains IAR Embedded Workbench settings for ILINK/IELFTOOL and modified .icf files for placing the CHECKSUM section at a specified place in memory.

There are three IAR Embedded Workbench project configurations in the example 'Example (1 range, 3 diff. locations)' , where the checksum is placed in three different ways:

  • Placed at the very end of ROM (configuration PlaceEndOfROM).
  • Placed before the start of the application code (configuration PlaceInFirstBlock).
  • Placed after the end of the application code (configuration PlaceInLastBlock).

Alternative solution using checksum-start and checksum-end markers

The normal procedure for checksum calculation is to open the dialog "Options > Linker > Checksum" and enable "Fill unused memory", specify a fill pattern, also specify address range (start address, end address) - next enable "Generate checksum" and specify the algorithm.

The inconvenience of using this dialog is that the start address and end address have to be adjusted to match the application.

The start address is usually fixed, but the end address need to be adjusted from time to time, and this alternative solution is trying to overcome this inconvenience by using special symbols (checksum_start and checksum_end).

The main differences in the project Example (alternative solution).zip, compared to 'Example (1 range, 3 diff. locations) configuration PlaceInLastBlock' are:

  • Menu "Project > Options... > Linker > Checksum > mark "Fill unused code memory" is NOT selected.
  • The C/C++ source adds checksum-start and checksum-end markers:
__root const unsigned char checksum_start @ "checksum_start_mark" = 0;
__root const unsigned char checksum_end[4] @ "checksum_end_mark" = {0,0,0,0xEE};

// The last byte is the actual "checksum area end mark"
// Any values can be assigned to the start and end markers.
// The keyword __root is only needed if the source is not referencing these symbols.
  • The linker configuration file adds a ROM-block with fixed order:
define block ROM_CONTENT with fixed order

{
    readonly section checksum_start_mark,
    readonly,
    readonly section checksum_end_mark,
    readonly section checksum
};
place in ROM_region { block ROM_CONTENT };
  • The C/C++ source references the checksum value using an extern declaration
extern const unsigned short ielftool_checksum;
  • The "Project > Options > Linker > Extra Options > Use command line options" adds --place_holder to create/reserve space for the ielftool_checksum symbol and --keep to make sure that the symbol is included
--place_holder ielftool_checksum,2,checksum,4
--keep=ielftool_checksum
  • The "Project > Options > Build Actions > Post-build command line" adds the ielftool.exe command
ielftool --fill 0xFF;checksum_start-checksum_end+3
--checksum ielftool_checksum:2,crc16,0x0;checksum_start-checksum_end+3
--verbose "$TARGET_PATH$" "$TARGET_PATH$"

Note:

The block ROM_CONTENT does not include the interrupt vector, which is normally located at address 0x0 and placed with a specific "place at" directive. To include the interrupt vector in the checksum calculation, replace "checksum_start" with 0x0 in the ielftool.exe command line for both option --fill and option --checksum.

 

All product names are trademarks or registered trademarks of their respective owners.

We do no longer support Internet Explorer. To get the best experience of iar.com, we recommend upgrading to a modern browser such as Chrome or Edge.