Subtraction Algorithms

Hexmate has several checksum algorithms that subtract 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. In other respects, these algorithms are identical to the addition algorithms described in Addition Algorithms.

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 subtractions of values starting at address data,
// truncating and returning the result
// data: the address of the first value to subtract
// n:    the number of subtractions to perform
// offset: the intial value to which the subtraction is added
resultType ck_sub(const readType *data, unsigned n, resultType offset)
{
    resultType chksum;
    chksum = offset;
    while(n--) {
        chksum -= *data;
        data++;
    }
    return chksum;
}

Here is how this function might be used when, for example, a 4-byte-wide checksum is to be calculated from the addition of 2-byte-wide values over the address range 0x0 to 0x7fd, starting with an offset of 0x0. 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=0-7fd@7fe,offset=0,algorithm=-2,width=-4

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

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