IAR EWARM Checksum Technical Note

IELFTOOL Checksum - Basic actions

EW targets: ARM, RH850, RX, SH, STM8
EW component: General issues
Last update: September 6, 2013

Below follows the steps needed to set up an CRC16 checksum calcuation, both in the EW-tool-chain and in the application.

This note applies to...
...these versions of the following Embedded Workbenches products:
EWARM 5.11 (and later) - - - EWRX 2.10 (and later)
EWSH 2.10 (and later) - - - EWSTM8 1.10 (and later)

Include checksum calculation source in your application.

The minimum requirement is that your source uses the symbol __checksum.

Note: If your source doesn't use the symbol __checksum you will get an error message from IELFTOOL: "The string '__checksum' was not found in the string table".

To be able to link anyway, you can turn on Project > Options... > Linker > Extra Options > mark "Use command line options" and add the command line option "--keep __checksum".

Checksum calculation in the application

The supplied example(s) shows how to use the CRC16 checksum calculation. In the C source of the application you need to add the actual generic C source to calculate the same checksum value as EWARM calculates. There are two variants of the calculation:

Fast -- Short execution time, but it uses up more ROM/flash for a constant table.

Slow -- It uses less ROM/flash but more execution time.

Please note:

The checksum calculation must not (in order to work) be made over the bytes where the checksum is placed in memory. One solution is to place the checksum at the beginning or end of memory. So the bytes (1, 2 or 4) where the checksum is saved must be excluded from the checksum calculation.

If the slow function is used, you must make a final call to the checksum calculation with the same number of bytes, with value 0x00, as you have bytes (1, 2 or 4) in the checksum. See the 'Example (1 range, 3 diff. locations)' project for details. (Use the link to the upper right.)

Turn on checksum calculation in the options for the linker

You can use these options either in the Embedded Workbench or on the command line. If using command line the command should first run the linker, then run the IELFTOOL.

In the EW you set up calculation of the checksum in menu Project > Options > Linker > Checksum options tab.

The options used in the (place first) example are:
Fill unused code memory
Fill pattern 0xFF (can be any pattern)
Start address 0x0 (adjust to your application)
End address 0xFFFB (adjust to your application)
Generate checksum; size = 2 bytes; CRC16; Complement = as is; Bit order = MSB first; initial value = 0.

The corresponding command line is:

ielftool --fill 0xFF;0x0-0xfffb --checksum __checksum:2,crc16,0x0;0x0-0xfffb 

There are 2 requirements that you have to fulfill to make this work. - See the next 2 parts of the tech note.

Select the address range to be checksummed.
Select where the chacksum will be placed.
Select the range for which checksum will be calculated

The checksum should (normally) cover all non-RAM bytes of the application, excluding the bytes where the checksum is placed.

The way to get knowledge about this is to turn on

menu Project > Options... > Linker > Checksum > mark "Fill unused code memory" and mark "Generate checksum"

menu Project > Options... > Linker > List > mark "Generate linker map file"

menu Tools > Options... > Messages > Show build messages > All

Add usage of the symbol __checksum in your application.

Perform one build.

Then look in the .map file to see where the symbol __checksum is placed.

Look in the "Build Window" to see the memory range that will be used in the checksum calculation.

Specify where the checksum itself is stored

This is done in the .icf file. The following example will place it at the end of memory.

Add this in the .icf file.

place at end of ROM_region { ro section .checksum };

In the 'Example (1 range, 3 diff. locations)', configuration 'PlaceEndOfROM' , the start address is 0x0 and the end address is 0xFFFB.

Please Note: There are several other solutions on how/where to place the checksum in memory. - These solutions are presented in the Tech Note 62709.

EWARM - Example (1 range, 3 diff. locations) (ZIP, 170 KB)

Technical note 11927
Checksum calculation with IELFTOOL after linking with ILINK

Technical note 52619
IELFTOOL Checksum - When using LPC device

Technical note 53274
IELFTOOL Checksum - over several ranges

Technical note 62709
IELFTOOL Checksum - Placing the checksum

Checksum calculation with IELFTOOL after linking with ILINK

Technical Note 11927

EW targets: ARM, RH850, RX, SH, STM8
EW component: General issues
Keywords: checksum calculation
Last update: February 4, 2015

This tech note is the 'main tech note' for the set of tech notes that covers different aspects of CRC checksum calculations in these EW-tool-chains.

The set of tech notes applies to...
...these versions of the Embedded Workbenches (uses Elf/Dwarf as file format in the tool-chain). The Tech Note applies to:

EWARM 5.11 (and later)

EWRX 2.10 (and later)

EWSH 2.10 (and later)

EWSTM8 1.10 (and later)

Background information on IEFLTOOL
In IAR tool-chains with the ILINK linker, the checksum calculation is done in IELFTOOL. So if a checksum is to be calculated then ILINK links the application, passes on (to IELFTOOL) the commands for filling and checksum calculation, and IELFTOOL does the calculation.

Overview - I.e. steps that has to be done in order to get a checksum in the output of the project

You need to include checksum calculation source in your application.

You need to turn on checksum calculation in the options for the linker.

You must select for which memory range IELFTOOL will calculate the checksum.

You must decide where the checksum will reside in the memory.

Details of the checksum calculation
The details (of checksum) are placed in these sub tech notes:

IELFTOOL Checksum - Basic actions - Tech note 65473 - The steps needed to set it up.

IELFTOOL Checksum - Placing the checksum - Tech note 62709 - The locations where the checksum can be placed.

IELFTOOL Checksum - over several ranges - Tech note 53274.

The details (for specific devices) are placed in these sub tech notes:

Calculate CRC32 as in STM32 hardware (v.5.50 and later) - Tech note 64424 - (using the built-in hardware CRC32 calculator in STM32 devices from ST).

Calculate CRC32 as in K60 hardware - Tech note 85753 - (using the built-in hardware CRC32 calculator in K60-device from Freescale).

IELFTOOL Checksum - When using LPC device - Tech note 52619 - (Extra considerations for LPC devices from NXP.)


More information
There is more information about the checksum in the .htm read-me-file for ILINKand in the .pdf DevelopmentGuide file. These files are found in your installation.

Mr. Ross N. Williams at Rocksoft in Australia have written, what he calls: A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS and this document can be down loaded from the link CRC explained by Mr. Ross N. Williams to the right.

IELFTOOL Checksum - over several ranges

Technical Note 53274

EW targets: ARM, RH850, RX, SH, STM8
EW component: General issues
Keywords: checksum calculation
Last update: September 6, 2013

The checksum calculation can be made over several ranges. If several ranges are used, then please note:

The GUI accepts only one range, so you need to turn off the checksum options, and instead...

...enter some command line options in Project > Options... > Linker > "Extra options".

...enter some command line options to "build actions" > "post build command line"

Be careful to calculate (in the application) the ranges with the lowest address range first and so on.

The calculation (in the application) will not be able to use checksum symbols (defined by the GUI), so you need to make some effort to use correct ranges in the application.

Two ranges - two checksum values

See example project 'Example: Two ranges two checksums' .

The 1st range is 0x1006000 to 0x102FFFB and the 2nd range 0x1030000 to 0x103EFFB.

Three changes are required:

1. The changes for ILINK are made at "Project > Options... > Linker > Extra options".

Add the following:

--place_holder __checksum1,2,.checksum1,1
--place_holder __checksum2,2,.checksum2,1
--define_symbol __checksum_begin1=0x1006000  
--define_symbol __checksum_end1=0x102FFFB 
--define_symbol __checksum_begin2=0x1030000  
--define_symbol __checksum_end2=0x103EFFB 

2. Use a post-build command line to perform the checksum calculation, by setting "Project > Options... > Build Actions > Post-build command line"

ielftool --fill 0xFF;0x1006000-0x102FFFB  --fill 0xFF;0x1030000-0x103EFFB 
--checksum __checksum1:2,crc16,0x0;0x1006000-0x102FFFB 
--checksum __checksum2:2,crc16,0x0;0x1030000-0x103EFFB 
--verbose "$TARGET_PATH$" "$TARGET_PATH$"

3. In the .icf file, define memory ranges and where to place the checksums:

define symbol __ICFEDIT_region_ROM_start__   = 0x1006000;
define symbol __ICFEDIT_region_ROM_end__     = 0x102FFFF;

define symbol __ICFEDIT_region_PFM_start__   = 0x1030000;
define symbol __ICFEDIT_region_PFM_end__     = 0x103EFFF;

define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__
to __ICFEDIT_region_ROM_end__];

define region PFM_region = mem:[from __ICFEDIT_region_PFM_start__ 
to __ICFEDIT_region_PFM_end__];

place at end of ROM_region { readonly section .checksum1 };
place at end of PFM_region { readonly section .checksum2 };
Two ranges - one checksum value

See example project 'Example: Two ranges one checksum' .

The 1st range is 0x1006000 to 0x102FFFB and the 2nd range is 0x1030000 to 0x103EFFF.

Three changes are required:

1. The changes for ILINK are made at "Project > Options... > Linker > Extra options".

Add the following:

--place_holder __checksum,2,.checksum,1
--define_symbol __checksum_begin1=0x1006000
--define_symbol __checksum_end1=0x102FFFB
--define_symbol __checksum_begin2=0x1030000
--define_symbol __checksum_end2=0x103EFFF

2. Use a post-build command line to perform the checksum calculation, by setting "Project > Options... > Build Actions > Post-build command line"

ielftool --fill 0xFF;0x1006000-0x102FFFB --fill 0xFF;0x1030000-0x103EFFF
--checksum __checksum1:2,crc16,0x0;0x1006000-0x102FFFB;0x1030000-0x103EFFF
--verbose "$TARGET_PATH$" "$TARGET_PATH$"

3. In the .icf file, define memory ranges and where to place the checksum:

define symbol __ICFEDIT_region_ROM_start__   = 0x1006000;
define symbol __ICFEDIT_region_ROM_end__     = 0x102FFFF;

define symbol __ICFEDIT_region_PFM_start__   = 0x1030000;
define symbol __ICFEDIT_region_PFM_end__     = 0x103EFFF;

define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__
to __ICFEDIT_region_ROM_end__];

define region PFM_region = mem:[from __ICFEDIT_region_PFM_start__
to __ICFEDIT_region_PFM_end__];

place at end of ROM_region { readonly section .checksum };


Example: Two ranges two checksums (ZIP, 103 KB)

Example: Two ranges one checksum (ZIP, 100 KB)

 

IELFTOOL Checksum - Placing the checksum

Technical Note 62709

EW targets: ARM, RH850, RX, SH, STM8
EW component: General issues
Keywords: checksum calculation
Last update: September 6, 2013

Here follows the possibilities for placement of the checksum.

Place last in memory.

Covered in the tech 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 'Example (1 range, 3 diff. locations)', 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, i.e. 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)', 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)', includes the actual generic C source to calculate the same checksum value as IELFTOOL produces in its CRC calculation. It also contains EW settings for ILINK/IELFTOOL and modified .icf files for placing the CHECKSUM section at a specified place in memory.

There are three EW 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 'Example (alternative solution with start and end markers)', 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 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 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 command line for both option --fill and option --checksum.

 

Output Converter - Binary file does not include checksum

EW targets: ARM, RX, SH, STM8
EW component: General issues
Last update: February 12, 2013
Problem

The option "Output Converter > Output > Generate additional output > Output format:

binary" is set, but the checksum of the application is not included in the generated binary file.

Solution

Probably the checksum is calculated using a post-build command line.

See Technical Note 52619 (Solution 2 and 3) about using a .bat file invoked from the post-build command line.

IELFTOOL Checksum - When using LPC device

Technical Note 52619

EW targets: ARM
EW component: General issues
Keywords: checksum calculation
Last update: February 12, 2013

Note for NXP LPC devices:
The LPC devices needs a special checksum to be placed at a specific address (in the vector table). IAR Embedded Workbench will automatically calculate this checksum and place it.
But the CRC checksum that these set of tech notes discuss must not be calculated over this special checksum in the vector table.

Problem 1 - ielftool error

When you build you get the error
ielftool error: Checksums have dependencies

The error is issued since both the vector table checksum and the application checksum are calculated by the same ielftool command.

Solution 1 - exclude the vector table

The solution is to exclude the vector table from the calculation of the application checksum, which can be done by setting the start address to the first address that follows the vector table.

Change option "Linker > Checksum > Start address" from 0x0 to 0x40.

(Check the .map file to find the end address of section .intvec)

Problem 2 - checksum have to include the vector table

The checksum of your application have to include the vector table too, but "Solution 1" excludes the vector table.

Solution 2 - use post-build command line

If you use a post-build command line, the two checksums will be calculated by separate ielftool commands, i.e. avoiding the dependency that caused the ielftool error, and the start address 0x0 can be used.

1. Deselect option "Linker > Checksum > Fill unused code memory".

2. Add option "Linker > Extra Options > Use command line options"

--place_holder  __checksum,2,.checksum,1
--define_symbol __checksum_begin=0x0
--define_symbol __checksum_end=0xfffb

3. Set option "Build Actions > Post-build command line"

ielftool --fill 0xFF;0x0-0xfffb --checksum __checksum:2,crc16,0x0;0x0-0xfffb
--verbose "$TARGET_PATH$" "$TARGET_PATH$"
Problem 3 - binary file does not include checksum

The option "Output Converter > Output > Generate additional output > Output format: binary" is set, but the checksum of the application is not included in the generated binary file.

The reason is that the binary file is generated after linking but before the post-build action, i.e. before the checksum is calculated by the post-build action!

Solution 3 - use post-build .bat file

The solution is to let the post-build command line invoke a .bat file that first calculates the checksum and then generates additional output.

See example project 'EWARM - Example (LPC device)' (link to the upper right).

EWARM - Example (LPC device) (ZIP, 114 KB)

Note: This example project is based on the 'Example (1 range, 3 diff. locations)', configuration 'PlaceEndOfROM'.

The target is changed to LPC1768 in order to provoke the ielftool error, but the address range over which the checksum is calculated is still the same as in the original example project.

Description:

1. Set option "Build Actions > Post-build command line"

$PROJ_DIR$\post-build.bat "$TARGET_BPATH$"

2. Create file post-build.bat in the project folder, with the following content:

set OUT=%1.out
set HEX=%1.hex
set BIN=%1.bin

:: calculate application checksum
ielftool --fill 0xFF;0x0-0xfffb --checksum __checksum:2,crc16,0x0;0x0-0xfffb
--verbose %OUT% %OUT%

:: generate additional ouput: hex
ielftool.exe --ihex --verbose %OUT% %HEX%

:: generate additional ouput: binary
ielftool.exe --bin --verbose %OUT% %BIN%

 

posted @ 2015-06-23 02:03  IAmAProgrammer  阅读(4326)  评论(0编辑  收藏  举报