From 27e68234b729fa7f71d596cf702b96a544e3d11c Mon Sep 17 00:00:00 2001 From: Doug Weibel Date: Wed, 23 Nov 2011 21:46:11 -0700 Subject: [PATCH] Simplified logging logic for finding start/end of log files --- ArduPlane/Log.pde | 217 +++++++++++++++++++++------------------------- 1 file changed, 99 insertions(+), 118 deletions(-) diff --git a/ArduPlane/Log.pde b/ArduPlane/Log.pde index 0e2eef8c2f..9e9ba04613 100644 --- a/ArduPlane/Log.pde +++ b/ArduPlane/Log.pde @@ -259,146 +259,127 @@ static void get_log_boundaries(byte log_num, int & start_page, int & end_page) } else { end_page = find_last_log_page((uint16_t)log_num); - if(log_num==1) - start_page = 1; - else - if(log_num == g.log_last_filenumber - num + 1) { - start_page = find_last_log_page(g.log_last_filenumber) + 1; + if(log_num==1) { + DataFlash.StartRead(DF_LAST_PAGE); + if(DataFlash.GetFileNumber() == 0xFFFF) { + start_page = 1; } else { - start_page = find_last_log_page((uint16_t)(log_num-1)) + 1; + start_page = find_last() + 1; } + } else { + if(log_num == g.log_last_filenumber - num + 1) { + start_page = find_last() + 1; + } else { + start_page = find_last_log_page((uint16_t)log_num-1) + 1; + } + } } if(start_page == DF_LAST_PAGE+1 || start_page == 0) start_page=1; } +static bool check_wrapped(void) +{ + DataFlash.StartRead(DF_LAST_PAGE); + if(DataFlash.GetFileNumber() == 0xFFFF) + return 0; + else + return 1; +} + // This function finds the last page of the last file -// It also cleans up in the situation where a file was initiated, but no pages written static int find_last(void) { - int16_t num; - do - { - num = find_last_log_page(g.log_last_filenumber); - if (num == -1) g.log_last_filenumber.set_and_save(g.log_last_filenumber - 1); - } while (num == -1); - return num; +uint16_t look; +uint16_t bottom = 1; +uint16_t top = DF_LAST_PAGE; +uint32_t look_hash; +uint32_t bottom_hash; +uint32_t top_hash; + + DataFlash.StartRead(bottom); + bottom_hash = DataFlash.GetFileNumber()<<16 | DataFlash.GetFilePage(); + + while(top-bottom > 1) + { + look = (top+bottom)/2; + DataFlash.StartRead(look); + look_hash = DataFlash.GetFileNumber()<<16 | DataFlash.GetFilePage(); + if (look_hash >= 0xFFFF0000) look_hash = 0; + + if(look_hash < bottom_hash) { + // move down + top = look; + } else { + // move up + bottom = look; + bottom_hash = look_hash; + } + } + + DataFlash.StartRead(top); + top_hash = DataFlash.GetFileNumber()<<16 | DataFlash.GetFilePage(); + if (top_hash >= 0xFFFF0000) top_hash = 0; + if (top_hash > bottom_hash) + { + return top; + } else { + return bottom; + } } // This function finds the last page of a particular log file static int find_last_log_page(uint16_t log_number) { - uint16_t bottom_page; - uint16_t bottom_page_file; - uint16_t bottom_page_filepage; - uint16_t top_page; - uint16_t top_page_file; - uint16_t top_page_filepage; - uint16_t look_page; - uint16_t look_page_file; - uint16_t look_page_filepage; +uint16_t look; +uint16_t bottom; +uint16_t top; +uint32_t look_hash; +uint32_t check_hash; - bottom_page = 1; - DataFlash.StartRead(bottom_page); - bottom_page_file = DataFlash.GetFileNumber(); - bottom_page_filepage = DataFlash.GetFilePage(); - - // First see if the logs are empty. If so we will exit right away. - if(bottom_page_file == 0XFFFF) { - return 0; - } - - top_page = DF_LAST_PAGE; - DataFlash.StartRead(top_page); - top_page_file = DataFlash.GetFileNumber(); - top_page_filepage = DataFlash.GetFilePage(); - - - while((top_page - bottom_page) > 1) { - look_page = ((long)top_page + (long)bottom_page) / 2L; - - DataFlash.StartRead(look_page); - look_page_file = DataFlash.GetFileNumber(); - look_page_filepage = DataFlash.GetFilePage(); - - // We have a lot of different logic cases dependant on if the log space is overwritten - // and where log breaks might occur relative to binary search points. - // Someone could make work up a logic table and simplify this perhaps, or perhaps - // it is easier to interpret as is. - - if (look_page_file == 0xFFFF) { - top_page = look_page; - top_page_file = look_page_file; - top_page_filepage = look_page_filepage; - - } else if (look_page_file == log_number && bottom_page_file == log_number && top_page_file == log_number) { - // This case is typical if a single file fills the log and partially overwrites itself - if (bottom_page_filepage < top_page_filepage) { - bottom_page = look_page; - bottom_page_file = look_page_file; - bottom_page_filepage = look_page_filepage; - } else { - top_page = look_page; - top_page_file = look_page_file; - top_page_filepage = look_page_filepage; - } - - } else if (look_page_file == log_number && look_page_file ==bottom_page_file) { - if (bottom_page_filepage < look_page_filepage) { - bottom_page = look_page; - bottom_page_file = look_page_file; - bottom_page_filepage = look_page_filepage; - } else { - top_page = look_page; - top_page_file = look_page_file; - top_page_filepage = look_page_filepage; - } - - } else if (look_page_file == log_number) { - bottom_page = look_page; - bottom_page_file = look_page_file; - bottom_page_filepage = look_page_filepage; - - } else if(look_page_file < log_number && bottom_page_file > look_page_file && bottom_page_file <= log_number) { - top_page = look_page; - top_page_file = look_page_file; - top_page_filepage = look_page_filepage; - } else if(look_page_file < log_number) { - bottom_page = look_page; - bottom_page_file = look_page_file; - bottom_page_filepage = look_page_filepage; - - } else if(look_page_file > log_number && top_page_file < look_page_file && top_page_file >= log_number) { - bottom_page = look_page; - bottom_page_file = look_page_file; - bottom_page_filepage = look_page_filepage; + if(check_wrapped()) + { + DataFlash.StartRead(1); + bottom = DataFlash.GetFileNumber(); + if (bottom > log_number) + { + bottom = find_last(); + top = DF_LAST_PAGE; } else { - top_page = look_page; - top_page_file = look_page_file; - top_page_filepage = look_page_filepage; + bottom = 1; + top = find_last(); } - - // End while - } - - if (bottom_page_file == log_number && top_page_file == log_number) { - if( bottom_page_filepage < top_page_filepage) - return top_page; - else - return bottom_page; - } else if (bottom_page_file == log_number) { - return bottom_page; - } else if (top_page_file == log_number) { - return top_page; } else { - return -1; + bottom = 1; + top = find_last(); } + + check_hash = (long)log_number<<16 | 0xFFFF; + + while(top-bottom > 1) + { + look = (top+bottom)/2; + DataFlash.StartRead(look); + look_hash = (long)DataFlash.GetFileNumber()<<16 | DataFlash.GetFilePage(); + if (look_hash >= 0xFFFF0000) look_hash = 0; + + if(look_hash > check_hash) { + // move down + top = look; + } else { + // move up + bottom = look; + } + } + + DataFlash.StartRead(top); + if (DataFlash.GetFileNumber() == log_number) return top; + DataFlash.StartRead(bottom); + if (DataFlash.GetFileNumber() == log_number) return bottom; + + return -1; } - - - - // Write an attitude packet. Total length : 10 bytes