/* start writing to a new log file */ uint16_t DataFlash_File::start_new_log(void) { stop_logging(); if (_read_fd != -1) { ::close(_read_fd); _read_fd = -1; } uint16_t log_num = find_last_log(); // re-use empty logs if possible if (_get_log_size(log_num) > 0 || log_num == 0) { log_num++; } if (log_num > MAX_LOG_FILES) { log_num = 1; } char *fname = _log_file_name(log_num); _write_fd = ::open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); free(fname); if (_write_fd == -1) { _initialised = false; return 0xFFFF; } // now update lastlog.txt with the new log number fname = _lastlog_file_name(); FILE *f = ::fopen(fname, "w"); fprintf(f, "%u\n", (unsigned)log_num); fclose(f); free(fname); return log_num; }
/* list available log numbers */ void DataFlash_File::ListAvailableLogs(AP_HAL::BetterStream *port) { uint16_t num_logs = get_num_logs(); int16_t last_log_num = find_last_log(); if (num_logs == 0) { port->printf_P(PSTR("\nNo logs\n\n")); return; } port->printf_P(PSTR("\n%u logs\n"), (unsigned)num_logs); for (uint16_t i=num_logs; i>=1; i--) { uint16_t log_num = last_log_num - i + 1; off_t size; char *filename = _log_file_name(log_num); if (filename != NULL) { size = _get_log_size(log_num); if (size != 0) { port->printf_P(PSTR("Log %u in %s of size %u\n"), (unsigned)log_num, filename, (unsigned)size); } free(filename); } } port->println(); }
/* get the number of logs - note that the log numbers must be consecutive */ uint16_t DataFlash_File::get_num_logs(void) { uint16_t ret; uint16_t high = find_last_log(); for (ret=0; ret<high; ret++) { if (_get_log_size(high - ret) <= 0) { break; } } return ret; }
/* start writing to a new log file */ uint16_t DataFlash_File::start_new_log(void) { stop_logging(); if (_open_error) { // we have previously failed to open a file - don't try again // to prevent us trying to open files while in flight return 0xFFFF; } if (_read_fd != -1) { ::close(_read_fd); _read_fd = -1; } uint16_t log_num = find_last_log(); // re-use empty logs if possible if (_get_log_size(log_num) > 0 || log_num == 0) { log_num++; } if (log_num > MAX_LOG_FILES) { log_num = 1; } char *fname = _log_file_name(log_num); _write_fd = ::open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (_write_fd == -1) { _initialised = false; _open_error = true; int saved_errno = errno; ::printf("Log open fail for %s - %s\n", fname, strerror(saved_errno)); hal.console->printf("Log open fail for %s - %s\n", fname, strerror(saved_errno)); free(fname); return 0xFFFF; } free(fname); _write_offset = 0; _writebuf_head = 0; _writebuf_tail = 0; log_write_started = true; // now update lastlog.txt with the new log number fname = _lastlog_file_name(); FILE *f = ::fopen(fname, "w"); fprintf(f, "%u\r\n", (unsigned)log_num); fclose(f); free(fname); return log_num; }
/* list available log numbers */ void DataFlash_File::ListAvailableLogs(AP_HAL::BetterStream *port) { uint16_t num_logs = get_num_logs(); int16_t last_log_num = find_last_log(); if (num_logs == 0) { port->printf_P(PSTR("\nNo logs\n\n")); return; } port->printf_P(PSTR("\n%u logs\n"), (unsigned)num_logs); for (uint16_t i=num_logs; i>=1; i--) { uint16_t log_num = last_log_num - i + 1; off_t size; char *filename = _log_file_name(log_num); if (filename != NULL) { size = _get_log_size(log_num); if (size != 0) { struct stat st; if (stat(filename, &st) == 0) { struct tm *tm = gmtime(&st.st_mtime); port->printf_P(PSTR("Log %u in %s of size %u %u/%u/%u %u:%u\n"), (unsigned)log_num, filename, (unsigned)size, (unsigned)tm->tm_year+1900, (unsigned)tm->tm_mon+1, (unsigned)tm->tm_mday, (unsigned)tm->tm_hour, (unsigned)tm->tm_min); } } free(filename); } } port->println(); }
/* find size and date of a log */ void DataFlash_File::get_log_info(uint16_t log_num, uint32_t &size, uint32_t &time_utc) { size = _get_log_size(log_num); time_utc = _get_log_time(log_num); }
/* find the number of pages in a log */ void DataFlash_File::get_log_boundaries(uint16_t log_num, uint16_t & start_page, uint16_t & end_page) { start_page = 0; end_page = _get_log_size(log_num) / DATAFLASH_PAGE_SIZE; }