rlw has asked for the wisdom of the Perl Monks concerning the following question:
First draft: CRC the whole file and download the whole file to the module. This works just fine, CRC-wise. However, the data is sparse, so takes much longer than truely needed to download.
Second draft: Partion file into 32 byte blocks; CRC and download only the blocks with actual data. The data downloads fine, but the CRC check is "off by one".
Note that this error only occures when my CRC generator is run on a block-by-block basis, rather than the whole file all at once:
@data = read_data($infile); # @data is global $data[0x6FFE] = 0; # zero CRC $data[0x6FFF = 0; # locations $crc = crc16(0x0000, 0x6FFF, 0); # works $crc = 0; for ($a = 0x0000; $a < 0x6fff; $a += 32) { # final value next if (unusedBlock($a, 32); # off by one $crc = crc16($a, $a + 32, $crc); } $data[0x6FFE] = $crc >> 8; # save $data[0x6FFF] = $crc & 0xFF; # CRC write_data($outfile); # or write_data_blocks($outfile);
Obviously, the block-by-block CRC is based on fewer bytes than the full CRC, so is, as expected, different.
The module software is designed handle the data download in blocks, and, therefore, runs it CRC calculation block-by-block. In fact, even when the whole file is downloaded, it is still blocked. The difference is that all blocks are sent for the whole file, while only a subset for block-by-block.
Below are my Perl CRC routine (called by the above code) and the C source of the module's CRC routine.
sub crc16 ($$$) { my ($startadr, $endadr, $crc) = @_; my ($cadr, $adr, $i, $u, $d); for ($adr = $startadr; $adr <= $endadr; $adr++) { if (defined($data[$adr])) { $d = $data[$adr] & 0xFF; } else { $d = 0xFF; } $i = $crc >> 8; $crc <<= 8; $crc &= 0xFFFF; $crc |= $d; $crc ^= $crctable[$i]; } return $crc; }
void VerifyFlashBlock(UINT8 len, UINT16 address) { UINT8 byte_value; UINT8 crc_table_index; for (;len > 0; len--) { byte_value = _READ_BYTE_FROM_FLASH(address); crc_table_index = crc >> 8; crc = (crc << 8) | byte_value; crc = crc ^ _Crc_table[crc_table_index]; address++; buffer++; } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: CRC off-by-one
by Anonymous Monk on Mar 09, 2005 at 21:10 UTC | |
|
Re: CRC off-by-one
by Popcorn Dave (Abbot) on Mar 09, 2005 at 20:37 UTC |