Syntax
-H section ,...=method
Description
This option generates checksums of the sections in the section list into the CHECKSUM segment. Only the used content of the section is checksummed, not any of the unused part.
The method can be one of:
- sum A simple sum of all the data items.
- lrc or xor A longitudinal redundancy check of the data bytes, that is all bytes are exclusive-ored together.
- crc16 A CRC16 of the data using the generating polynomial 0x11021.
- crc32 A CRC32 of the data using the generating polynomial 0x104C11DB7.
Setting this in CrossStudio
- Select the project in the Project Explorer.
- In the Linker Options group edit the Checksum Sections property.
The Checksum Sections property is a list of comma-separated sections followed by '=' followed by the checksum method. If the method is omitted, CRC16 is assumed.
Example
To checksum the CODE and CONST sections using CRC16:
-HCODE,CONST=crc16
The CHECKSUM section generated by the linker for this will be as if the following assembly code had been written:
.PSECT "CHECKSUM" ___begin_CHECKSUM: ; CODE secion range and checksum DW ___begin_CODE DW ___end_CODE ___checksum_CODE:: DW crc-of-CODE-section ; CONST section range and checksum DW ___begin_CONST DW ___end_CONST ___checksum_CONST:: DW crc-of-CONST-section ; Sentinel DW 0 DW 0 ___end_CHECKSUM:
Note that the order of the checksums in the CHECKSUM section is undefined, so do not assume the order chosen by the linker will remain fixed. Always access the checksums using the public labels provided.
You can verify the individual checksums of the CODE and CONST sections checksummed above by using code along the following lines:
// External, provided as source code in the "src" directory
unsigned int __checksum_crc16(unsigned char *begin, unsigned char *end); // Symbols generated by the linker to delimit the CODE and CONST sections extern unsigned char __start_CODE[], __end_CODE[]; extern unsigned char __start_CONST[], __end_CONST[]; // Symbols generated by the linker for the CODE and CONST checksums extern unsigned int __checksum_CODE, __checksum_CONST; void main(void) { assert(__checksum_crc16(__start_CODE, __end_CODE) == __checksum_CODE); assert(__checksum_crc16(__start_CONST, __end_CONST) == __checksum_CONST); }
However, because the linker generates a table that has the addresses of the ranges checksummed and the expected checksum, you can check all the checksummed regions very simply:
// External, provided as source code in the "src" directory
unsigned int __checksum_crc16(unsigned char *begin, unsigned char *end); typedef struct {
unsigned char *begin; unsigned char *end; unsigned int checksum; } checksum_info; // Symbols generated by the linker for the CHECKSUM section extern checksum_info __begin_CHECKSUM[]; void main(void) { checksum_info *p; for (p = __begin_CHECKSUM; p->begin || p->end; ++p) assert(__checksum_crc16(p->begin, p->end) == p->checksum); }