8.2.4.1.2 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. See 8.2.4.1.1 Addition Algorithms for further information regarding the subtraction algorithms.
The function shown below can be customized to work with any combination of
data size (read_t
) and checksum width (result_t
).
#include <stdint.h>
typedef uint8_t read_t; // size of data values read and subtracted
typedef uint16_t result_t; // 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
result_t ck_sub(const read_t *data, unsigned n, result_t offset)
{
result_t 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.
xc8-cc
. 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
-ck=0-7fd@7fe+0g-2w-4
Adapt the following MPLAB XC8 code snippet for PIC devices, which calls
ck_sub()
and compares the runtime checksum with that stored by Hexmate at compile time.
extern const read_t ck_range[0x7fe/sizeof(read_t)] __at(0x0);
extern const result_t hexmate __at(0x7fe);
result_t result;
result = ck_sub(ck_range, sizeof(ck_range)/sizeof(read_t), 0x0);
if(result != hexmate)
ck_failure(); // take appropriate action