Hi all,
I want to add a sort of checksum in my F1612 to be able to verify the code
integrity each time it is power-up. I wonder if someone has already
experience this problem. I'd like to know few things like:
> 1- Which algorithm you use to obtain good performance without using a too
> big function code size
There are lots. A good and simple one is the 32-bit Fletcher checksum:
# Start with "data" and "wordcount" registers set appropriately
mov #-1,sumlo
mov #-1,sumhi
wordloop:
add @data+,sumlo
adc #0,sumlo
add sumlo,sumhi
adc #0,sumhi
sub #1,wordcount
jnz wordloop
# Final checksum in sumhi, sumlo
This is 8 cycles per word (4 per byte), and has the feature (which may
or my not be useful) that you can change a word of 0x0000 to 0xffff
without it noticing. You could unroll it n times, increasing the code
size by 8*(n-1) bytes, for a runtime of (5*n + 3)/2*n = 2.5 + 1.5/n
cycles per byte.
To verify it, you have two choices:
- You can either put the checksum "beside" the memory to be checked, and
not include it in the run-time checksum or
- You can patch 4 bytes in the checked region to make the checksum come
out to some expected value, typically all-ones. Then you can verify
it with and AND and a NOT.
The former has the convenient property that the all-zero value is not
possible to generate, so it can be used for a "checksum invalid" flag.
By some suitable bit-flipping, you could make the all-ones value be
the "reserved" value and have the processor compute and burn its own
checksum the first time it's booted in that case.
The latter isn't all that hard, and makes the verification code simpler.
The sumlo is simply the mod-65535 sum of all words of the source.
So you can compute the sum, then add 65535-sumlo to any word of the
source to make sumlo come out to 65535.
sumhi, the running sum of the sumlo values, is just
1*data[n-1] + 2*data[n-2] + 3*data[n-3] + ... + i*data[n-i] + ...
So given two adjacent words, data[k] and data[k+1], you can add x to the
sumhi value, without affecting sumlo, by adding x to data[k] and
subtracting x from data[k+1]. (All math mod-65535, of course.)
So you can patch *any* two adjacent words in a buffer to make the
checksum come out to any desired value by:
- Compute a prelimiary checksum.
- Change one of the words to make sumlo come out as desired.
(add desired.sumlo - prelim.sumlo)
- Figure out the effect that change would have on sumhi (adding x
to the word at data[n-i] adds i*x, td 65535, to sumhi)
- Make the desired correction to sumhi (corrhi = desired.sumhi - new.sumhi)
by adding corrhi to data[k] and subtracting it from data[k+1].
You can do all this with two non-adjacent words if you like, as long as
the distance between them is not a multiple of 3, 5, 17 or 257 words,
(i.e. gcd(distance,65535) == 0), but that's more complicated.
> 2- How you put it in the executable before download it using JTAG since it
> must be at a specific address for futur verification
That depends on how you make your image. I just make binary image files
and patch them in place as part of the build process. Or you could
export a binary image, compute the checksum correction, put the corrected
values into a very small source file, and re-link to get everything
right.