Mercurial > public > ostc4
comparison Discovery/Src/externLogbookFlash.c @ 557:2702bfa7b177
Stabilityfix: Do not trust lastDiveLogID == 0 at startup:
If dive settings are reset for some reason also the lastDiveLogID is set to 0. Most likly the consostency check will find a valid entry. But this entry might not be the last one => return an error value to trigger the find function. Calling "find" at every startup is normal behavior if TRUST_LOG_CONSISTENCY is not set and was default for a long time => low risk
In addition a check of the header adresses has been added to identify a potential error while writing log samples
| author | Ideenmodellierer |
|---|---|
| date | Thu, 12 Nov 2020 20:03:00 +0100 |
| parents | b1eee27cd02b |
| children | bc6c90e20d9e |
comparison
equal
deleted
inserted
replaced
| 556:eb2060caca7d | 557:2702bfa7b177 |
|---|---|
| 1399 { | 1399 { |
| 1400 uint8_t ret = 0; | 1400 uint8_t ret = 0; |
| 1401 uint8_t header1, header2; | 1401 uint8_t header1, header2; |
| 1402 uint8_t id; | 1402 uint8_t id; |
| 1403 convert_Type dataStart; | 1403 convert_Type dataStart; |
| 1404 convert_Type dataEnd; | |
| 1404 | 1405 |
| 1405 SSettings *settings = settingsGetPointer(); | 1406 SSettings *settings = settingsGetPointer(); |
| 1406 id = settings->lastDiveLogId; | 1407 id = settings->lastDiveLogId; |
| 1407 | 1408 |
| 1408 actualAddress = HEADERSTART + (0x800 * id); | 1409 if(settings->lastDiveLogId != 0) /* not trust LogID 0 which might be reset by a settings problem */ |
| 1409 ext_flash_read_block_start(); | 1410 { /* ==> Find function will be called restoring the Id belonging to the latest sample */ |
| 1410 ext_flash_read_block(&header1, EF_HEADER); | 1411 actualAddress = HEADERSTART + (0x800 * id); |
| 1411 ext_flash_read_block(&header2, EF_HEADER); | 1412 ext_flash_read_block_start(); |
| 1412 dataStart.u8bit.byteHigh = 0; | 1413 ext_flash_read_block(&header1, EF_HEADER); |
| 1413 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); | 1414 ext_flash_read_block(&header2, EF_HEADER); |
| 1414 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); | 1415 ext_flash_read_block_stop(); |
| 1415 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); | 1416 if((header1 == 0xFA) && (header2 == 0xFA)) /* Header is indicating the start of a dive */ |
| 1416 ext_flash_read_block_stop(); | 1417 { |
| 1417 if((header1 == 0xFA) && (header2 == 0xFA)) /* Header is indicating the start of a dive */ | 1418 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; |
| 1418 { | 1419 ext_flash_read_block_start(); |
| 1419 actualAddress = HEADERSTART + (0x800 * id) + HEADER2OFFSET; | 1420 ext_flash_read_block(&header1, EF_HEADER); |
| 1420 ext_flash_read_block_start(); | 1421 ext_flash_read_block(&header2, EF_HEADER); |
| 1421 ext_flash_read_block(&header1, EF_HEADER); | 1422 dataStart.u8bit.byteHigh = 0; |
| 1422 ext_flash_read_block(&header2, EF_HEADER); | 1423 ext_flash_read_block(&dataStart.u8bit.byteLow, EF_HEADER); |
| 1423 ext_flash_read_block_stop(); | 1424 ext_flash_read_block(&dataStart.u8bit.byteMidLow, EF_HEADER); |
| 1424 if((header1 == 0xFA) && (header2 == 0xFA)) /* Secondary header was written at the end of a dive */ | 1425 ext_flash_read_block(&dataStart.u8bit.byteMidHigh, EF_HEADER); |
| 1425 { | 1426 dataEnd.u8bit.byteHigh = 0; |
| 1426 ret = 1; /* => lastDiveLogID points to a valid dive entry */ | 1427 ext_flash_read_block(&dataEnd.u8bit.byteLow, EF_HEADER); |
| 1427 } | 1428 ext_flash_read_block(&dataEnd.u8bit.byteMidLow, EF_HEADER); |
| 1428 } | 1429 ext_flash_read_block(&dataEnd.u8bit.byteMidHigh, EF_HEADER); |
| 1430 ext_flash_read_block_stop(); | |
| 1431 | |
| 1432 if((header1 == 0xFA) && (header2 == 0xFA)) /* Secondary header was written at the end of a dive */ | |
| 1433 { | |
| 1434 if(dataStart.u32bit < dataEnd.u32bit) | |
| 1435 { | |
| 1436 ret = 1; /* => lastDiveLogID points to a valid dive entry */ | |
| 1437 } | |
| 1438 else /* check if address wrap is valid */ | |
| 1439 { | |
| 1440 if(ext_flash_SampleOverrunValid()) | |
| 1441 { | |
| 1442 ret = 1; | |
| 1443 } | |
| 1444 } | |
| 1445 } | |
| 1446 } | |
| 1447 } | |
| 1429 return ret; | 1448 return ret; |
| 1430 } | 1449 } |
| 1431 | 1450 |
| 1432 // =============================================================================== | 1451 // =============================================================================== |
| 1433 // ext_flash_repair_dive_log | 1452 // ext_flash_repair_dive_log |
| 2228 uint32_t curAddress, actualaddrbackup; | 2247 uint32_t curAddress, actualaddrbackup; |
| 2229 uint8_t tmpBuffer; | 2248 uint8_t tmpBuffer; |
| 2230 uint8_t emptyCellCnt = 0; | 2249 uint8_t emptyCellCnt = 0; |
| 2231 | 2250 |
| 2232 actualaddrbackup = actualAddress; | 2251 actualaddrbackup = actualAddress; |
| 2233 curAddress = SAMPLESTOP - 20; /* check the last 10 bytes of the last sample sector */ | 2252 curAddress = SAMPLESTOP - 20; /* check the last 20 bytes of the last sample sector */ |
| 2234 actualAddress = curAddress; | 2253 actualAddress = curAddress; |
| 2235 ext_flash_read_block_start(); | 2254 ext_flash_read_block_start(); |
| 2236 while(actualAddress < SAMPLESTOP) | 2255 while(actualAddress < SAMPLESTOP) |
| 2237 { | 2256 { |
| 2238 tmpBuffer = read_spi(HOLDCS);/* read data */ | 2257 tmpBuffer = read_spi(HOLDCS);/* read data */ |
| 2250 } | 2269 } |
| 2251 actualAddress = actualaddrbackup; | 2270 actualAddress = actualaddrbackup; |
| 2252 return jumpvalid; | 2271 return jumpvalid; |
| 2253 } | 2272 } |
| 2254 | 2273 |
| 2255 uint32_t ext_flash_AnalyseSampleBuffer(char *pstrResult) | 2274 uint32_t ext_flash_AnalyseSampleBuffer() |
| 2256 { | 2275 { |
| 2257 uint8_t sectorState[16]; /* samples are stored in 16 sector / 64k each */ | 2276 uint8_t sectorState[192]; /* samples are stored in 192 sector / 64k each */ |
| 2258 uint32_t curAddress = SAMPLESTART; | 2277 uint32_t curAddress = SAMPLESTART; |
| 2259 uint8_t curSector = 0; | 2278 uint8_t curSector = 0; |
| 2260 uint8_t samplebuffer[10]; | 2279 uint8_t samplebuffer[10]; |
| 2261 uint32_t actualAddressBackup = actualAddress; | 2280 uint32_t actualAddressBackup = actualAddress; |
| 2262 uint8_t emptyCellCnt = 0; | 2281 uint8_t emptyCellCnt = 0; |
| 2263 uint32_t i = 0; | 2282 uint32_t i = 0; |
| 2264 uint8_t startedSectors = 0; | 2283 uint8_t startedSectors = 0; |
| 2265 uint8_t lastSectorInuse = 0; | 2284 uint8_t lastSectorInuse = 0; |
| 2266 | 2285 |
| 2267 /* check if a sector is used till its end */ | 2286 /* check if a sector is used till its end */ |
| 2268 for(curSector = 0; curSector < 16; curSector++) | 2287 for(curSector = 0; curSector < 192; curSector++) |
| 2269 { | 2288 { |
| 2270 sectorState[curSector] = 0; | 2289 sectorState[curSector] = 0; |
| 2271 emptyCellCnt = 0; | 2290 emptyCellCnt = 0; |
| 2272 curAddress = SAMPLESTART + (curSector * 0x10000); /* set address to begin of sector and check if it is used */ | 2291 curAddress = SAMPLESTART + (curSector * 0x10000); /* set address to begin of sector and check if it is used */ |
| 2273 actualAddress = curAddress; | 2292 actualAddress = curAddress; |
| 2302 { | 2321 { |
| 2303 sectorState[curSector] |= SECTOR_INUSE; /* will become SECTOR_EMPTY if start is NOTUSED */ | 2322 sectorState[curSector] |= SECTOR_INUSE; /* will become SECTOR_EMPTY if start is NOTUSED */ |
| 2304 } | 2323 } |
| 2305 } | 2324 } |
| 2306 | 2325 |
| 2307 for(i=0;i<16;i++) | 2326 for(i=0;i<192;i++) |
| 2308 { | 2327 { |
| 2309 if( sectorState[i] == SECTOR_INUSE) | 2328 if( sectorState[i] == SECTOR_INUSE) |
| 2310 { | 2329 { |
| 2311 startedSectors++; | 2330 startedSectors++; |
| 2312 lastSectorInuse = i; | 2331 lastSectorInuse = i; |
| 2313 } | 2332 } |
| 2314 *(pstrResult+i) = sectorState[i] + 48; | |
| 2315 } | 2333 } |
| 2316 | 2334 |
| 2317 if(startedSectors > 1) /* more than one sector is in used => ring buffer corrupted */ | 2335 if(startedSectors > 1) /* more than one sector is in used => ring buffer corrupted */ |
| 2318 { | 2336 { |
| 2319 if(startedSectors == 2) /* only fix issue if only two sectors are in used. Otherwise fixing will cause more worries than help */ | 2337 if(startedSectors == 2) /* only fix issue if only two sectors are in used. Otherwise fixing will cause more worries than help */ |
| 2341 actualPointerSample = actualAddress; | 2359 actualPointerSample = actualAddress; |
| 2342 | 2360 |
| 2343 closeSectorAddress = settingsGetPointer()->logFlashNextSampleStartAddress & 0xFFFF0000; | 2361 closeSectorAddress = settingsGetPointer()->logFlashNextSampleStartAddress & 0xFFFF0000; |
| 2344 closeSectorAddress += 0xFFF5; /* to be used once next time a dive is logged. Needed because NextSampleID is derived at every startup */ | 2362 closeSectorAddress += 0xFFF5; /* to be used once next time a dive is logged. Needed because NextSampleID is derived at every startup */ |
| 2345 settingsGetPointer()->logFlashNextSampleStartAddress = actualPointerSample; /* store new position to be used for next dive */ | 2363 settingsGetPointer()->logFlashNextSampleStartAddress = actualPointerSample; /* store new position to be used for next dive */ |
| 2364 ext_flash_CloseSector(); | |
| 2346 } | 2365 } |
| 2347 } | 2366 } |
| 2348 actualAddress = actualAddressBackup; | 2367 actualAddress = actualAddressBackup; |
| 2349 *(pstrResult+i) = 0; | |
| 2350 return startedSectors; | 2368 return startedSectors; |
| 2351 } | 2369 } |
| 2352 | 2370 |
| 2353 uint32_t ext_flash_read_profilelength_small_header(uint32_t smallHeaderAddr) | 2371 uint32_t ext_flash_read_profilelength_small_header(uint32_t smallHeaderAddr) |
| 2354 { | 2372 { |
