7.2.4.1.1 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 from 1 to 8 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 (read_t
) and checksum width (result_t
).
#include <stdint.h>
typedef uint8_t read_t; // size of data values read and summed
typedef uint16_t result_t; // 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
result_t ck_add(const read_t *data, unsigned n, result_t offset)
{
result_t chksum;
chksum = offset;
while(n--) {
chksum += *data;
data++;
}
return chksum;
}
The read_t
and result_t
type definitions should be
adjusted to suit the data read/sum width and checksum result width, respectively. 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.
-ck=100-7fd@7fe+20g1w-2
Adapt the following MPLAB XC8 code snippet for PIC devices, which calls
ck_add()
and compares the runtime checksum with that stored by Hexmate at compile time.
extern const read_t ck_range[0x6fe/sizeof(read_t)] __at(0x100);
extern const result_t hexmate __at(0x7fe);
result_t result;
result = ck_add(ck_range, sizeof(ck_range)/sizeof(read_t), 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 read_t
width.
This is a non-issue if the size of read_t
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.