AP_Terrain: added checking of block CRCs on disk

this allows us to cope with SD card data corruption
This commit is contained in:
Andrew Tridgell 2014-07-22 19:23:04 +10:00
parent 0562907d9f
commit 28d6e39c4c
2 changed files with 21 additions and 2 deletions

View File

@ -159,7 +159,8 @@ AP_Terrain::grid_cache &AP_Terrain::find_grid(const struct grid_info &info)
// see if we have that grid // see if we have that grid
for (uint16_t i=0; i<TERRAIN_GRID_BLOCK_CACHE_SIZE; i++) { for (uint16_t i=0; i<TERRAIN_GRID_BLOCK_CACHE_SIZE; i++) {
if (cache[i].grid.lat == info.grid_lat && if (cache[i].grid.lat == info.grid_lat &&
cache[i].grid.lon == info.grid_lon) { cache[i].grid.lon == info.grid_lon &&
cache[i].grid.spacing == grid_spacing) {
cache[i].last_access_ms = hal.scheduler->millis(); cache[i].last_access_ms = hal.scheduler->millis();
return cache[i]; return cache[i];
} }
@ -597,6 +598,18 @@ void AP_Terrain::update(void)
} }
/*
get CRC for a block
*/
uint16_t AP_Terrain::get_block_crc(struct grid_block &block)
{
uint16_t saved_crc = block.crc;
block.crc = 0;
uint16_t ret = crc16_ccitt((const uint8_t *)&block, sizeof(block), 0);
block.crc = saved_crc;
return ret;
}
/* /*
open the current degree file open the current degree file
*/ */
@ -682,6 +695,9 @@ void AP_Terrain::write_block(void)
if (io_failure) { if (io_failure) {
return; return;
} }
disk_block.block.crc = get_block_crc(disk_block.block);
ssize_t ret = ::write(fd, &disk_block, sizeof(disk_block)); ssize_t ret = ::write(fd, &disk_block, sizeof(disk_block));
if (ret != sizeof(disk_block)) { if (ret != sizeof(disk_block)) {
#if TERRAIN_DEBUG #if TERRAIN_DEBUG
@ -720,7 +736,9 @@ void AP_Terrain::read_block(void)
disk_block.block.lat != lat || disk_block.block.lat != lat ||
disk_block.block.lon != lon || disk_block.block.lon != lon ||
disk_block.block.bitmap == 0 || disk_block.block.bitmap == 0 ||
disk_block.block.version != TERRAIN_GRID_FORMAT_VERSION) { disk_block.block.spacing != grid_spacing ||
disk_block.block.version != TERRAIN_GRID_FORMAT_VERSION ||
disk_block.block.crc != get_block_crc(disk_block.block)) {
#if TERRAIN_DEBUG #if TERRAIN_DEBUG
printf("read empty block at %ld %ld ret=%d\n", printf("read empty block at %ld %ld ret=%d\n",
(long)lat, (long)lat,

View File

@ -222,6 +222,7 @@ private:
disk IO functions disk IO functions
*/ */
int16_t find_io_idx(void); int16_t find_io_idx(void);
uint16_t get_block_crc(struct grid_block &block);
void check_disk_read(void); void check_disk_read(void);
void check_disk_write(void); void check_disk_write(void);
void io_timer(void); void io_timer(void);