Addition Algorithms

Hexmate has several simple checksum algorithms that sum data values over a range in the program image. These algorithms correspond to the selector values 1, 2, 3 and 4 in the algorithm suboption and read the data in the program image as 1, 2, 3 or 4 byte quantities, respectively. This summation is added to an initial value (offset) that is supplied to the algorithm via the same option. The width to which the final checksum is truncated is also specified by this option and can be 1, 2, 3 or 4 bytes. Hexmate will automatically store the checksum in the HEX file at the address specified in the checksum option.

The function shown below can be customized to work with any combination of data size (readType) and checksum width (resultType).

typedef unsigned char readType; // size of data values read and summed
typedef unsigned int  resultType; // size of checksum result
// add to offset n additions of values starting at address data,
// truncating and returning the result
// data: the address of the first value to sum
// n:    the number of sums to perform
// offset: the intial value to which the sum is added
resultType ck_add(const readType *data, unsigned n, resultType offset)
{
    resultType chksum;
    chksum = offset;
    while(n--) {
        chksum += *data;
        data++;
    }
    return chksum;
}

The readType and resultType type definitions should be adjusted to suit the data read/sum width and checksum result width, respectively. When using MPLAB XC8 and for a size of 1, use a char type; for a size of 4, use a long type, etc., or consider using the exact-width types provided by <stdint.h>. If you never use an offset, that parameter can be removed and chksum assigned 0 before the loop.

Here is how this function might be used when, for example, a 2-byte-wide checksum is to be calculated from the addition of 1-byte-wide values over the address range 0x100 to 0x7fd, starting with an offset of 0x20. The checksum is to be stored at 0x7fe and 0x7ff in little endian format. The following option is specified when building the project. In MPLAB X IDE, only enter the information to the right of the first = in the Checksum field in the Additional options Option category in the XC8 Linker category.

-mchecksum=100-7fd@7fe,offset=20,algorithm=1,width=-2

In your project, add the following code snippet which calls ck_add() and compare the runtime checksum with that stored by Hexmate at compile time.

extern const readType ck_range[0x6fe/sizeof(readType)] __at(0x100);
extern const resultType hexmate __at(0x7fe);
resultType result;
result = ck_add(ck_range, sizeof(ck_range)/sizeof(readType), 0x20);
if(result != hexmate)
    ck_failure();  // take appropriate action

This code uses the placeholder array, ck_range, to represent the memory over which the checksum is calculated and the variable hexmate is mapped over the locations where Hexmate will have stored its checksum result. Being extern and absolute, neither of these objects consume additional device memory. Adjust the addresses and sizes of these objects to match the option you pass to Hexmate.

Hexmate can calculate a checksum over any address range; however, the test function, ck_add(), assumes that the start and end address of the range being summed are a multiple of the readType width. This is a non-issue if the size of readType is 1. It is recommended that your checksum specification adheres to this assumption, otherwise you will need to modify the test code to perform partial reads of the starting and/or ending data values. This will significantly increase the code complexity.