From ddfbe366bdad900aa851de69b83fac145e93d04d Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 1 Mar 2025 13:12:56 -0500 Subject: [PATCH 01/16] Attempting to implement ping pong buffer to only keep last 30 seconds of logging data as well as not overwriting existing data by checking file names. A lot of changes were added as I did a lot of work before commiting. --- telemetry/src/logging/logging.c | 322 +++++++++++++++++++++++++++----- 1 file changed, 274 insertions(+), 48 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index ba43ec0..4c2972b 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -2,8 +2,16 @@ #include #include #include +#include #include "logging.h" +#include +#include +#include +#include + +#include +#include /* The maximum size of a log file's file name. */ @@ -21,138 +29,335 @@ #define err_to_ptr(err) ((void *)((err))) +/* The number of times opening a log file will be attempted */ + +#define NUM_TIMES_TRY_OPEN 3 + /* - * Logging thread which runs to log data to the SD card. + * Return if length of log filename is less than MAX_FILENAME defined length. */ -void *logging_main(void *arg) { +bool log_filename_length_ok(char *filename){ + return strlen(filename) < MAX_FILENAME; +} +int find_max_boot_number(char *file){ + DIR *directory_pointer = opendir("./"); + struct dirent *entry; + + // char *file = CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog"; + // char *file = CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/flog"; + int max_boot_number = 0; + + if (directory_pointer != NULL) + { + while ((entry = readdir(directory_pointer)) != NULL) + { + if (strstr(entry->d_name, file) != NULL) + // Ex.) find /log/elog in /log/elog2. Index should be 8 to get number 2 + { + int index = strlen(file); + char char_num = entry->d_name[index]; + int boot_number = char_num - '0'; // Convert from character to int using ASCII values + if (boot_number > max_boot_number) + { + max_boot_number = boot_number; + } + } + } + + (void)closedir(directory_pointer); + return max_boot_number; + } + else + { + perror("Couldn't open the directory: "); + return -1; + } +} + +/* + * Logging thread which runs to log data to the SD card. + */ +void *logging_main(void *arg) +{ int err; size_t written; enum flight_state_e flight_state; rocket_state_t *state = ((rocket_state_t *)(arg)); uint32_t version = 0; - char flight_filename[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + - MAX_FILENAME]; + char flight_filename[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + MAX_FILENAME]; char land_filename[sizeof(CONFIG_INSPACE_TELEMETRY_LANDED_FS) + MAX_FILENAME]; + FILE *storage_file_1 = NULL; // File descriptors for first logging file + FILE *storage_file_2 = NULL; // File descriptors for second logging file + FILE *active_storage_file; // File descriptor for active logging file + struct stat file_info; // Stat struct to hold fstat return + + time_t base_time; // Time that file was last modified + time_t new_time; // Time to check against base_time to see if 30 seconds has passed + + struct timespec base_timespec; + struct timespec new_timespec; + + #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logging thread started.\n"); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ /* Generate flight log file name TODO: use sequence numbers */ - snprintf(flight_filename, sizeof(flight_filename), FLIGHT_FNAME_FMT, 0); + /* TODO: Find a way that If data already exists, don't overwrite/delete that data. + Example: We get data during launch, but turn off stack when we land. + On boot, make user we don't overwrite old data*/ - /* Open storage location in append mode */ + int max_flight_log_boot_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog"); + if (max_flight_log_boot_number < 0) + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error finding max boot number: return (%d)\n", max_flight_log_boot_number); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } - FILE *storage = fopen(flight_filename, "ab"); - if (storage == NULL) { + snprintf(flight_filename, sizeof(flight_filename), FLIGHT_FNAME_FMT, max_flight_log_boot_number); + + if (!log_filename_length_ok(flight_filename)) //Check log filename length + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename, MAX_FILENAME); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + + for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. + { + storage_file_1 = fopen(flight_filename, "rb+"); // Create file for reading and writing + if (storage_file_1 == NULL) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error opening log file 1 (Attempt %d)'%s': %d\n", i, flight_filename, err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + + //TODO: check errno values (if needed) + } + + usleep(1 * 1000); // Sleep for 1 millisecond before trying again + } + + if (storage_file_1 == NULL) + { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error opening log file 1 '%s': %d\n", flight_filename, err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + pthred_exit(err_to_ptr(err)); // TODO: fail more gracefully + } + + // enum flight_state_e last_flight_state = NULL; + active_storage_file = storage_file_1; + + err = fstat(active_storage_file, &file_info); + if (err) + { err = errno; - fprintf(stderr, "Error opening log file '%s': %d\n", flight_filename, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error using fstat: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + fclose(active_storage_file); } - /* Infinite loop to handle states */ - for (;;) { + //Save the time the file was last modified + base_timespec.tv_sec = file_info.st_mtime; + // file_info.st_mtim.tv_nsec; + // base_time = file_info.st_mtimensec; Do we need nanosecond precision/Can we support it? + + /* Infinite loop to handle states */ + for (;;) + { err = state_get_flightstate(state, &flight_state); + if (err) + { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - if (err) { fprintf(stderr, "Error getting flight state: %d\n", err); - } #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - - switch (flight_state) { + fclose(active_storage_file); + // TODO: figure out fail conditions + } + + switch (flight_state) + { case STATE_IDLE: /* Purposeful fall-through */ - case STATE_AIRBORNE: { + + //Switch between files every 30 seconds + case STATE_AIRBORNE: + { /* Infinite loop to log data */ /* Wait for the data to have a change */ err = state_wait_for_change(state, &version); // TODO: handle error + if (err) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during state_wait_for_change: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } /* Log data */ + // Sample logging + uint8_t sample_buf[1] = {1}; + written = fwrite(sample_buf, 1, 1, active_storage_file); + + if (/* 30 seconds passed */) + { + /* Create new log file */ + for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. + { + // TODO: Use different flight_filename than first file + // storage_file_2 = open(flight_filename, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file + storage_file_2 = fopen(flight_filename, "rb+"); // Create file + if (storage_file_2 == NULL) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename, err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + + // TODO: check errno values + + usleep(1 * 1000); // Sleep for 1 millisecond before trying again + continue; + } + + break; + } + + if (storage_file_2 == NULL) + { + err = errno; + pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully + } + + active_storage_file = storage_file_2; + } + err = state_read_lock(state); // TODO: handle error - written = fwrite(&state->data, sizeof(state->data), 1, storage); + if (err) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during state_read_lock: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + + written = fwrite(&state->data, sizeof(state->data), 1, active_storage_file); + // written = write(active_storage_file, sizeof(state->data), 1); #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logged %u bytes\n", written * sizeof(state->data)); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - if (written == 0) { + if (written == 0) + { // TODO: Handle error (might happen if file got too large, start // another file) } err = state_unlock(state); // TODO: handle error + if (err) + { + err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - if (err) { fprintf(stderr, "Error releasing read lock: %d\n", err); - } #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } - /* If we are in the idle state, only write the latest n seconds of data - */ - if (flight_state == STATE_IDLE) { + /* If we are in the idle state, only write the latest n seconds of data*/ + if (flight_state == STATE_IDLE) + { // TODO: check file position } - } break; + } + break; - case STATE_LANDED: { + case STATE_LANDED: + { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Copying files to extraction file system.\n"); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ /* Generate log file name for extraction file system */ - snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, - 0); // TODO: use log seq number + int max_extraction_log_file_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/flog%d.bin"); + + snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number); // TODO: use log seq number /* Open extraction log file */ - FILE *log = fopen(land_filename, "wb"); - if (log == NULL) { + int extract_log_fd; + for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. + { + extract_log_fd = fopen(land_filename, "wb"); + if (extract_log_fd == NULL) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error (Attempt %d) opening the extraction log file '%s': %d\n", i, flight_filename, err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + + // TODO: check errno values + } + else + { + break; + } + + usleep(1 * 1000); // Sleep for 1 millisecond before trying again + } + + if (extract_log_fd == NULL) + { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, - "Couldn't open extraction log file '%s' with error: %d\n", - land_filename, err); + fprintf(stderr, "Couldn't open extraction log file '%s' with error: %d\n", land_filename, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ pthread_exit(err_to_ptr(err)); } - /* Roll power-safe log file pointer back to beginning */ - fseek(storage, 0, SEEK_SET); // TODO: handle error - + err = fseek(active_storage_file, 0, SEEK_SET); // TODO: handle error + if (err) + { + /* Handle Error */ + } + /* Copy from one to the other using a buffer */ uint8_t buf[BUFSIZ]; size_t nbytes = 0; - while (!feof(storage)) { - nbytes = sizeof(buf) * fread(buf, sizeof(buf), 1, storage); + while (!feof(active_storage_file)) + { + nbytes = sizeof(buf) * fread(buf, sizeof(buf), 1, active_storage_file); if (nbytes == 0) break; - nbytes = sizeof(buf) * fwrite(buf, nbytes, 1, storage); + nbytes = sizeof(buf) * fwrite(buf, nbytes, 1, extract_log_fd); } /* Now that logs are copied to FAT partition, move back to the idle state * for another go. + * flight_state = STATE_IDLE; */ - if (fclose(log) != 0) { - // TODO: handle error - err = errno; + if (close(extract_log_fd) != 0) + { + // TODO: handle error + err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, - "Couldn't close extraction log file '%s' with error: %d\n", - land_filename, err); + fprintf(stderr, "Couldn't close extraction log file '%s' with error: %d\n", land_filename, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } @@ -162,12 +367,33 @@ void *logging_main(void *arg) { } #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - if (fclose(storage) != 0) { + if (close(active_storage_file) != 0) + { err = errno; fprintf(stderr, "Failed to close flight logfile handle: %d\n", err); } #else - fclose(storage); + close(active_storage_file); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ pthread_exit(err_to_ptr(err)); + + + //Trying to make same as code above +// if (close(storage_file_1) != 0) +// { +// err = errno; +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Failed to close flight logfile 1 handle: %d\n", err); +// #endif +// } + +// if (close(storage_file_2) != 0) +// { +// err = errno; +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Failed to close flight logfile 2 handle: %d\n", err); +// #endif +// } + +// pthread_exit(err_to_ptr(err)); } From 7e28eccb65a1fd77f54712c3b16f1067027f3a49 Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 1 Mar 2025 13:15:33 -0500 Subject: [PATCH 02/16] Removed function for checking file name length --- telemetry/src/logging/logging.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 4c2972b..b10f405 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -33,12 +33,6 @@ #define NUM_TIMES_TRY_OPEN 3 -/* - * Return if length of log filename is less than MAX_FILENAME defined length. - */ -bool log_filename_length_ok(char *filename){ - return strlen(filename) < MAX_FILENAME; -} int find_max_boot_number(char *file){ DIR *directory_pointer = opendir("./"); @@ -120,7 +114,7 @@ void *logging_main(void *arg) snprintf(flight_filename, sizeof(flight_filename), FLIGHT_FNAME_FMT, max_flight_log_boot_number); - if (!log_filename_length_ok(flight_filename)) //Check log filename length + if (strlen(flight_filename) > MAX_FILENAME) // Check log filename length { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename, MAX_FILENAME); From fdc01333a6cadae6a82416d31a9bad7decce2faa Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 1 Mar 2025 13:50:26 -0500 Subject: [PATCH 03/16] Added error check to make sure log file number is for sure a digit. Added timespec_diff function to find difference in time between two timespec structs. I am using clock_gettime() to get the current system time to compare to time of the last modification. --- telemetry/src/logging/logging.c | 69 ++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index b10f405..6d8c2c1 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -47,10 +48,18 @@ int find_max_boot_number(char *file){ while ((entry = readdir(directory_pointer)) != NULL) { if (strstr(entry->d_name, file) != NULL) - // Ex.) find /log/elog in /log/elog2. Index should be 8 to get number 2 { + // Ex.) find /log/elog in /log/elog2. Index should be 8 to get number 2 int index = strlen(file); char char_num = entry->d_name[index]; + if (!isdigit(char_num)) + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Number after logging file does not exist (%s)\n", file); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + return -1; + } + int boot_number = char_num - '0'; // Convert from character to int using ASCII values if (boot_number > max_boot_number) { @@ -69,6 +78,14 @@ int find_max_boot_number(char *file){ } } +/* + * Returns double time difference between two timespec structs + */ +double timespec_diff(struct timespec *start, struct timespec *end) +{ + return (end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec) / 1e9; +} + /* * Logging thread which runs to log data to the SD card. */ @@ -82,17 +99,13 @@ void *logging_main(void *arg) char flight_filename[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + MAX_FILENAME]; char land_filename[sizeof(CONFIG_INSPACE_TELEMETRY_LANDED_FS) + MAX_FILENAME]; - FILE *storage_file_1 = NULL; // File descriptors for first logging file - FILE *storage_file_2 = NULL; // File descriptors for second logging file - FILE *active_storage_file; // File descriptor for active logging file - struct stat file_info; // Stat struct to hold fstat return - - time_t base_time; // Time that file was last modified - time_t new_time; // Time to check against base_time to see if 30 seconds has passed - - struct timespec base_timespec; - struct timespec new_timespec; + FILE *storage_file_1 = NULL; // File pointer for first logging file + FILE *storage_file_2 = NULL; // File pointer for second logging file + FILE *active_storage_file; // File pointer for active logging file + struct stat file_info; // Stat struct to hold fstat return + struct timespec base_timespec; // Time that file was last modified + struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logging thread started.\n"); @@ -161,9 +174,7 @@ void *logging_main(void *arg) //Save the time the file was last modified base_timespec.tv_sec = file_info.st_mtime; - - // file_info.st_mtim.tv_nsec; - // base_time = file_info.st_mtimensec; Do we need nanosecond precision/Can we support it? + base_timespec.tv_nsec = 0; /* Infinite loop to handle states */ for (;;) @@ -202,11 +213,30 @@ void *logging_main(void *arg) /* Log data */ + /* Store current system time as new_timespec */ + if (clock_gettime(CLOCK_REALTIME, new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during clock_gettime: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + + // Sample logging uint8_t sample_buf[1] = {1}; written = fwrite(sample_buf, 1, 1, active_storage_file); - if (/* 30 seconds passed */) + double diff = timespec_diff(&base_timespec, &new_timespec); + if (diff < 0) + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", diff); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + + + if (diff >= 30.0) { /* Create new log file */ for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. @@ -237,6 +267,15 @@ void *logging_main(void *arg) } active_storage_file = storage_file_2; + + /* Store current system time as the new base time */ + if (clock_gettime(CLOCK_REALTIME, base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during clock_gettime: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } } err = state_read_lock(state); // TODO: handle error From 295d4099a011409d89c9b9ba359d754db0d00dd0 Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 1 Mar 2025 13:55:08 -0500 Subject: [PATCH 04/16] Spacing fixes --- telemetry/src/logging/logging.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 6d8c2c1..646a1af 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -102,10 +102,10 @@ void *logging_main(void *arg) FILE *storage_file_1 = NULL; // File pointer for first logging file FILE *storage_file_2 = NULL; // File pointer for second logging file FILE *active_storage_file; // File pointer for active logging file - + struct stat file_info; // Stat struct to hold fstat return - struct timespec base_timespec; // Time that file was last modified - struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed + struct timespec base_timespec; // Time that file was last modified + struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logging thread started.\n"); @@ -121,7 +121,7 @@ void *logging_main(void *arg) if (max_flight_log_boot_number < 0) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error finding max boot number: return (%d)\n", max_flight_log_boot_number); + fprintf(stderr, "Error finding max boot number: return (%d)\n", max_flight_log_boot_number); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } From 249663d1d3dcff70cc49abf0b41d350dcb475fc3 Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 3 Mar 2025 19:04:27 -0500 Subject: [PATCH 05/16] Converted all file descriptions to FILE streams and added FILE * for the extraction file. Changed the way flight and extraction log file names are constructed. Fixed some typos in variable names. Added teardown function. --- telemetry/src/logging/logging.c | 221 ++++++++++++++++++++++---------- 1 file changed, 154 insertions(+), 67 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 646a1af..fa8c7e4 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -20,11 +20,11 @@ /* The format for flight log file names */ -#define FLIGHT_FNAME_FMT CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/flog%d.bin" +#define FLIGHT_FNAME_FMT CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/flog_boot%d_%d.bin" /* The format for extraction log file names */ -#define EXTR_FNAME_FMT CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog%d.bin" +#define EXTR_FNAME_FMT CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog_boot%d_%d.bin" /* Cast an error to a void pointer */ @@ -39,8 +39,6 @@ int find_max_boot_number(char *file){ DIR *directory_pointer = opendir("./"); struct dirent *entry; - // char *file = CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog"; - // char *file = CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/flog"; int max_boot_number = 0; if (directory_pointer != NULL) @@ -96,13 +94,16 @@ void *logging_main(void *arg) enum flight_state_e flight_state; rocket_state_t *state = ((rocket_state_t *)(arg)); uint32_t version = 0; - char flight_filename[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + MAX_FILENAME]; + char flight_filename1[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + MAX_FILENAME]; + char flight_filename2[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + MAX_FILENAME]; char land_filename[sizeof(CONFIG_INSPACE_TELEMETRY_LANDED_FS) + MAX_FILENAME]; FILE *storage_file_1 = NULL; // File pointer for first logging file FILE *storage_file_2 = NULL; // File pointer for second logging file FILE *active_storage_file; // File pointer for active logging file + FILE *extract_storage_file; // File pointer for extraction logging file + struct stat file_info; // Stat struct to hold fstat return struct timespec base_timespec; // Time that file was last modified struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed @@ -111,13 +112,9 @@ void *logging_main(void *arg) printf("Logging thread started.\n"); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - /* Generate flight log file name TODO: use sequence numbers */ - - /* TODO: Find a way that If data already exists, don't overwrite/delete that data. - Example: We get data during launch, but turn off stack when we land. - On boot, make user we don't overwrite old data*/ + /* Generate flight log file names using the boot number */ - int max_flight_log_boot_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog"); + int max_flight_log_boot_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/elog_boot"); if (max_flight_log_boot_number < 0) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -125,23 +122,30 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - snprintf(flight_filename, sizeof(flight_filename), FLIGHT_FNAME_FMT, max_flight_log_boot_number); + snprintf(flight_filename1, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number, 1); + snprintf(flight_filename2, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number, 2); - if (strlen(flight_filename) > MAX_FILENAME) // Check log filename length + if (strlen(flight_filename1) > MAX_FILENAME) // Check log filename length + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename1, MAX_FILENAME); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + if (strlen(flight_filename2) > MAX_FILENAME) // Check log filename length { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename, MAX_FILENAME); + fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename2, MAX_FILENAME); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. { - storage_file_1 = fopen(flight_filename, "rb+"); // Create file for reading and writing + storage_file_1 = fopen(flight_filename1, "rb+"); // Create file for reading and writing if (storage_file_1 == NULL) { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 1 (Attempt %d)'%s': %d\n", i, flight_filename, err); + fprintf(stderr, "Error opening log file 1 (Attempt %d)'%s': %d\n", i, flight_filename1, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ //TODO: check errno values (if needed) @@ -153,15 +157,14 @@ void *logging_main(void *arg) if (storage_file_1 == NULL) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 1 '%s': %d\n", flight_filename, err); + fprintf(stderr, "Error opening log file 1 (%s): %d\n", flight_filename1, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ pthred_exit(err_to_ptr(err)); // TODO: fail more gracefully } - // enum flight_state_e last_flight_state = NULL; active_storage_file = storage_file_1; - err = fstat(active_storage_file, &file_info); + err = fstat(fileno(active_storage_file), &file_info); if (err) { err = errno; @@ -171,10 +174,10 @@ void *logging_main(void *arg) fclose(active_storage_file); } - //Save the time the file was last modified - base_timespec.tv_sec = file_info.st_mtime; - base_timespec.tv_nsec = 0; + base_timespec = (struct timespec){file_info.st_mtime, 0}; + // base_timespec.tv_sec = file_info.st_mtime; + // base_timespec.tv_nsec = 0; /* Infinite loop to handle states */ for (;;) @@ -188,13 +191,88 @@ void *logging_main(void *arg) fclose(active_storage_file); // TODO: figure out fail conditions } - + +// err = fstat(fileno(active_storage_file), &file_info); +// if (err) +// { +// err = errno; +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Error using fstat: %d\n", err); +// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ +// fclose(active_storage_file); +// } + switch (flight_state) { case STATE_IDLE: /* Purposeful fall-through */ - //Switch between files every 30 seconds + // Switch between files every 30 seconds + + + /* Store current system time as new_timespec */ + if (clock_gettime(CLOCK_REALTIME, new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during clock_gettime: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + + double time_diff = timespec_diff(&base_timespec, &new_timespec); + if (time_diff < 0) + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + + if (time_diff >= 30.0) + { + if (active_storage_file == storage_file_1) + { + /* Create new log file */ + for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. + { + // storage_file_2 = open(flight_filename2, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file + storage_file_2 = fopen(flight_filename2, "rb+"); // Create file + if (storage_file_2 == NULL) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + + // TODO: check errno values + usleep(1 * 1000); // Sleep for 1 millisecond before trying again + continue; + } + + break; + } + + if (storage_file_2 == NULL) + { + err = errno; + pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully + } + + active_storage_file = storage_file_2; + + /* Store current system time as the new base time */ + if (clock_gettime(CLOCK_REALTIME, base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during clock_gettime: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + } + else if (active_storage_file == storage_file_2) + { + active_storage_file = storage_file_1; + } + } case STATE_AIRBORNE: { @@ -202,7 +280,7 @@ void *logging_main(void *arg) /* Wait for the data to have a change */ - err = state_wait_for_change(state, &version); // TODO: handle error + err = state_wait_for_change(state, &version); if (err) { err = errno; @@ -213,6 +291,10 @@ void *logging_main(void *arg) /* Log data */ + // Sample logging + uint8_t sample_buf[1] = {1}; + written = fwrite(sample_buf, 1, 1, active_storage_file); + /* Store current system time as new_timespec */ if (clock_gettime(CLOCK_REALTIME, new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { @@ -221,11 +303,6 @@ void *logging_main(void *arg) fprintf(stderr, "Error during clock_gettime: %d\n", err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - - - // Sample logging - uint8_t sample_buf[1] = {1}; - written = fwrite(sample_buf, 1, 1, active_storage_file); double diff = timespec_diff(&base_timespec, &new_timespec); if (diff < 0) @@ -241,14 +318,13 @@ void *logging_main(void *arg) /* Create new log file */ for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. { - // TODO: Use different flight_filename than first file - // storage_file_2 = open(flight_filename, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file - storage_file_2 = fopen(flight_filename, "rb+"); // Create file + // storage_file_2 = open(flight_filename2, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file + storage_file_2 = fopen(flight_filename2, "rb+"); // Create file if (storage_file_2 == NULL) { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename, err); + fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ // TODO: check errno values @@ -278,7 +354,7 @@ void *logging_main(void *arg) } } - err = state_read_lock(state); // TODO: handle error + err = state_read_lock(state); if (err) { @@ -299,7 +375,7 @@ void *logging_main(void *arg) // another file) } - err = state_unlock(state); // TODO: handle error + err = state_unlock(state); if (err) { err = errno; @@ -324,43 +400,43 @@ void *logging_main(void *arg) /* Generate log file name for extraction file system */ - int max_extraction_log_file_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/flog%d.bin"); + int max_extraction_log_file_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_LANDED_FS "/flog_boot"); - snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number); // TODO: use log seq number + snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number); /* Open extraction log file */ - int extract_log_fd; for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. { - extract_log_fd = fopen(land_filename, "wb"); - if (extract_log_fd == NULL) + extract_storage_file = fopen(land_filename, "wb"); + if (extract_storage_file == NULL) { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error (Attempt %d) opening the extraction log file '%s': %d\n", i, flight_filename, err); + fprintf(stderr, "Error (Attempt %d) opening the extraction log file '%s': %d\n", i, land_filename, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ // TODO: check errno values + usleep(1 * 1000); // Sleep for 1 millisecond before trying again } else { break; - } - - usleep(1 * 1000); // Sleep for 1 millisecond before trying again + } } - if (extract_log_fd == NULL) + if (extract_storage_file == NULL) { + // If reach here, all attempts to open log file have failed, fatal error + err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Couldn't open extraction log file '%s' with error: %d\n", land_filename, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ pthread_exit(err_to_ptr(err)); } + /* Roll power-safe log file pointer back to beginning */ - err = fseek(active_storage_file, 0, SEEK_SET); // TODO: handle error if (err) { @@ -368,7 +444,6 @@ void *logging_main(void *arg) } /* Copy from one to the other using a buffer */ - uint8_t buf[BUFSIZ]; size_t nbytes = 0; @@ -377,7 +452,7 @@ void *logging_main(void *arg) nbytes = sizeof(buf) * fread(buf, sizeof(buf), 1, active_storage_file); if (nbytes == 0) break; - nbytes = sizeof(buf) * fwrite(buf, nbytes, 1, extract_log_fd); + nbytes = sizeof(buf) * fwrite(buf, nbytes, 1, extract_storage_file); } /* Now that logs are copied to FAT partition, move back to the idle state @@ -385,9 +460,8 @@ void *logging_main(void *arg) * flight_state = STATE_IDLE; */ - if (close(extract_log_fd) != 0) + if (fclose(extract_storage_file) != 0) { - // TODO: handle error err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Couldn't close extraction log file '%s' with error: %d\n", land_filename, err); @@ -411,22 +485,35 @@ void *logging_main(void *arg) pthread_exit(err_to_ptr(err)); - //Trying to make same as code above -// if (close(storage_file_1) != 0) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Failed to close flight logfile 1 handle: %d\n", err); -// #endif -// } +/* Teardown */ + teardown(storage_file_1, storage_file_2, extract_storage_file) -// if (close(storage_file_2) != 0) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Failed to close flight logfile 2 handle: %d\n", err); -// #endif -// } +} -// pthread_exit(err_to_ptr(err)); +void teardown(FILE *flight_log_1, FILE* flight_log_2, FILE* extraction_file_ptr) +{ + int err; + if (fclose(flight_log_1) != 0) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Failed to close flight logfile 1 handle: %d\n", err); +#endif + } + + if (fclose(flight_log_2) != 0) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Failed to close flight logfile 2 handle: %d\n", err); +#endif + } + + if (fclose(extraction_file_ptr) != 0) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Failed to close extraction logfile handle: %d\n", err); +#endif + } } From 4b76073bf17668209275e2fbcf9ddc6861cfcf3b Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 3 Mar 2025 19:42:26 -0500 Subject: [PATCH 06/16] Added file behaviour pseudocode at top of file. Commented out repetitve logic in the IDLE state that is also done in the AIRBORNE state. Will remove it if not needed --- telemetry/src/logging/logging.c | 172 +++++++++++++++++++------------- 1 file changed, 101 insertions(+), 71 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index fa8c7e4..51c8d6b 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -34,6 +34,44 @@ #define NUM_TIMES_TRY_OPEN 3 +/* + * Logging Pseudocode: + * + * Find previous max boot number + * Create file names with boot number that is max boot number + 1 + * Open file 1 + * Set the active file to file 1 + * Get base time to the last modification time of file 1 (would be creation time) + * + * Enter loop: + * Get flight state + * If in IDLE state: Want to switch between two files every 30 seconds until launch + * Get the current time + * If current time - base time >= 30 seconds: + * Switch to other file + * If active file == file 1: + * Open file 2 + * Switch active file to file 2 + * Else if active file == file 2: + * Switch active file to file 1 + + * Else if in AIRBORNE state: + * Wait for data to change + * Log data to active file + * Set new_timespec to current system time + * + * + * Else if in LANDED state: + * Create file name for extraction file based on previous max boot number + * Open extraction file + * Copy from the active file to the extraction file + * Close extraction file + * Go to IDLE state + * + * Teardown + * Close files + * Exit thread + */ int find_max_boot_number(char *file){ DIR *directory_pointer = opendir("./"); @@ -79,7 +117,7 @@ int find_max_boot_number(char *file){ /* * Returns double time difference between two timespec structs */ -double timespec_diff(struct timespec *start, struct timespec *end) +double timespec_diff(struct timespec *end, struct timespec *start) { return (end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec) / 1e9; } @@ -122,16 +160,16 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - snprintf(flight_filename1, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number, 1); - snprintf(flight_filename2, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number, 2); + snprintf(flight_filename1, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 1); + snprintf(flight_filename2, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 2); - if (strlen(flight_filename1) > MAX_FILENAME) // Check log filename length + if (strlen(flight_filename1) > MAX_FILENAME) // Check log 1 filename length { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename1, MAX_FILENAME); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - if (strlen(flight_filename2) > MAX_FILENAME) // Check log filename length + if (strlen(flight_filename2) > MAX_FILENAME) // Check log 2 filename length { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename2, MAX_FILENAME); @@ -208,71 +246,69 @@ void *logging_main(void *arg) /* Purposeful fall-through */ // Switch between files every 30 seconds - - - /* Store current system time as new_timespec */ - if (clock_gettime(CLOCK_REALTIME, new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? - { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during clock_gettime: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - } - double time_diff = timespec_diff(&base_timespec, &new_timespec); - if (time_diff < 0) - { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - } + /* Store current system time in new_timespec */ +// if (clock_gettime(CLOCK_REALTIME, new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? +// { +// err = errno; +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Error during clock_gettime: %d\n", err); +// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ +// } - if (time_diff >= 30.0) - { - if (active_storage_file == storage_file_1) - { - /* Create new log file */ - for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. - { - // storage_file_2 = open(flight_filename2, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file - storage_file_2 = fopen(flight_filename2, "rb+"); // Create file - if (storage_file_2 == NULL) - { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ +// double time_diff = timespec_diff(&new_timespec, &base_timespec); +// if (time_diff < 0) +// { +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); +// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ +// } + +// if (time_diff >= 30.0) +// { +// if (active_storage_file == storage_file_1) +// { +// /* Create new log file */ +// for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. +// { +// storage_file_2 = fopen(flight_filename2, "rb+"); // Create file +// if (storage_file_2 == NULL) +// { +// err = errno; +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); +// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - // TODO: check errno values - usleep(1 * 1000); // Sleep for 1 millisecond before trying again - continue; - } +// // TODO: check errno values +// usleep(1 * 1000); // Sleep for 1 millisecond before trying again +// continue; +// } - break; - } +// break; +// } - if (storage_file_2 == NULL) - { - err = errno; - pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully - } +// if (storage_file_2 == NULL) +// { +// err = errno; +// pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully +// } - active_storage_file = storage_file_2; +// active_storage_file = storage_file_2; - /* Store current system time as the new base time */ - if (clock_gettime(CLOCK_REALTIME, base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? - { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during clock_gettime: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - } - } - else if (active_storage_file == storage_file_2) - { - active_storage_file = storage_file_1; - } - } +// /* Store current system time as the new base time */ +// if (clock_gettime(CLOCK_REALTIME, base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? +// { +// err = errno; +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Error during clock_gettime: %d\n", err); +// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ +// } +// } +// else if (active_storage_file == storage_file_2) +// { +// active_storage_file = storage_file_1; +// } +// } case STATE_AIRBORNE: { @@ -304,7 +340,7 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - double diff = timespec_diff(&base_timespec, &new_timespec); + double diff = timespec_diff(&new_timespec, &base_timespec); if (diff < 0) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -344,7 +380,7 @@ void *logging_main(void *arg) active_storage_file = storage_file_2; - /* Store current system time as the new base time */ + /* Set Base time to current system time */ if (clock_gettime(CLOCK_REALTIME, base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { err = errno; @@ -355,7 +391,6 @@ void *logging_main(void *arg) } err = state_read_lock(state); - if (err) { err = errno; @@ -365,7 +400,6 @@ void *logging_main(void *arg) } written = fwrite(&state->data, sizeof(state->data), 1, active_storage_file); - // written = write(active_storage_file, sizeof(state->data), 1); #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logged %u bytes\n", written * sizeof(state->data)); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ @@ -399,13 +433,10 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ /* Generate log file name for extraction file system */ - int max_extraction_log_file_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_LANDED_FS "/flog_boot"); - snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number); /* Open extraction log file */ - for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. { extract_storage_file = fopen(land_filename, "wb"); @@ -428,7 +459,6 @@ void *logging_main(void *arg) if (extract_storage_file == NULL) { // If reach here, all attempts to open log file have failed, fatal error - err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Couldn't open extraction log file '%s' with error: %d\n", land_filename, err); From eb4d0f44c870cfcd4d1180695102a743b6fa344e Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 8 Mar 2025 13:46:01 -0500 Subject: [PATCH 07/16] "Added function to swap active log file. Now check for error when getting file descriptor for active storage file before calling fstat on it. Changed some variable names for better readability and commented out some code." --- telemetry/src/logging/logging.c | 187 +++++++++++++++++++++++--------- 1 file changed, 133 insertions(+), 54 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 51c8d6b..3514e85 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -114,6 +114,59 @@ int find_max_boot_number(char *file){ } } +int switch_active_log_file(FILE **active_storage_file, FILE **storage_file_1, FILE **storage_file_2, char **flight_filename2) +{ + int err; + if (*active_storage_file == *storage_file_1) + { + if (*storage_file_2 == NULL) + { + for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. + { + *storage_file_2 = fopen(flight_filename2, "rb+"); // Create file + if (*storage_file_2 == NULL) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error opening log file 2 '%s': %d\n", *flight_filename2, err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + + // TODO: check errno values + usleep(1 * 1000); // Sleep for 1 millisecond before trying again + continue; + } + + break; + } + + if (*storage_file_2 == NULL) + { + return -1; + } + + *active_storage_file = *storage_file_2; + } + + else + { + *active_storage_file = *storage_file_1; + } + } + + // If file_2 is currently active, that means file_1 was opened successfully, so just switch the pointer + else if (*active_storage_file == *storage_file_2) + { + if (*storage_file_1 == NULL) + { + return -1; + } + + *active_storage_file = *storage_file_1; + } + + return 0; +} + /* * Returns double time difference between two timespec structs */ @@ -136,15 +189,15 @@ void *logging_main(void *arg) char flight_filename2[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + MAX_FILENAME]; char land_filename[sizeof(CONFIG_INSPACE_TELEMETRY_LANDED_FS) + MAX_FILENAME]; - FILE *storage_file_1 = NULL; // File pointer for first logging file - FILE *storage_file_2 = NULL; // File pointer for second logging file - FILE *active_storage_file; // File pointer for active logging file + FILE *storage_file_1 = NULL; // File pointer for first logging file + FILE *storage_file_2 = NULL; // File pointer for second logging file + FILE *active_storage_file = NULL; // File pointer for active logging file - FILE *extract_storage_file; // File pointer for extraction logging file + FILE *extract_storage_file; // File pointer for extraction logging file - struct stat file_info; // Stat struct to hold fstat return - struct timespec base_timespec; // Time that file was last modified - struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed + struct stat file_info; // Stat struct to hold fstat return + struct timespec base_timespec; // Time that file was last modified + struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logging thread started.\n"); @@ -202,7 +255,17 @@ void *logging_main(void *arg) active_storage_file = storage_file_1; - err = fstat(fileno(active_storage_file), &file_info); + int fd = fileno(active_storage_file); + if (fd < 0) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error using fileno: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + fclose(active_storage_file); + } + + err = fstat(fd, &file_info); if (err) { err = errno; @@ -248,14 +311,14 @@ void *logging_main(void *arg) // Switch between files every 30 seconds /* Store current system time in new_timespec */ -// if (clock_gettime(CLOCK_REALTIME, new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? +// if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? // { // err = errno; // #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) // fprintf(stderr, "Error during clock_gettime: %d\n", err); // #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ // } - +// // double time_diff = timespec_diff(&new_timespec, &base_timespec); // if (time_diff < 0) // { @@ -263,7 +326,7 @@ void *logging_main(void *arg) // fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); // #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ // } - +// // if (time_diff >= 30.0) // { // if (active_storage_file == storage_file_1) @@ -278,25 +341,25 @@ void *logging_main(void *arg) // #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) // fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); // #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - +// // // TODO: check errno values // usleep(1 * 1000); // Sleep for 1 millisecond before trying again // continue; // } - +// // break; // } - +// // if (storage_file_2 == NULL) // { // err = errno; // pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully // } - +// // active_storage_file = storage_file_2; - +// // /* Store current system time as the new base time */ -// if (clock_gettime(CLOCK_REALTIME, base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? +// if (clock_gettime(CLOCK_REALTIME, &base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? // { // err = errno; // #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -328,11 +391,11 @@ void *logging_main(void *arg) /* Log data */ // Sample logging - uint8_t sample_buf[1] = {1}; - written = fwrite(sample_buf, 1, 1, active_storage_file); + // uint8_t sample_buf[1] = {1}; + // written = fwrite(sample_buf, 1, 1, active_storage_file); /* Store current system time as new_timespec */ - if (clock_gettime(CLOCK_REALTIME, new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? + if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -340,48 +403,58 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - double diff = timespec_diff(&new_timespec, &base_timespec); - if (diff < 0) + double time_diff = timespec_diff(&new_timespec, &base_timespec); + if (time_diff < 0) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", diff); + fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - - if (diff >= 30.0) + if (time_diff >= 30.0) { - /* Create new log file */ - for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. + // Switch active log file + err = switch_active_log_file(&active_storage_file, &storage_file_1, &storage_file_2, &flight_filename2); + if (err < 0) { - // storage_file_2 = open(flight_filename2, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file - storage_file_2 = fopen(flight_filename2, "rb+"); // Create file - if (storage_file_2 == NULL) - { - err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); + fprintf(stderr, "Error switching active log file: %d\n", err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - - // TODO: check errno values - - usleep(1 * 1000); // Sleep for 1 millisecond before trying again - continue; - } - - break; - } - - if (storage_file_2 == NULL) - { err = errno; pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully } - active_storage_file = storage_file_2; +// /* Create new log file */ +// for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. +// { +// // storage_file_2 = open(flight_filename2, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file +// storage_file_2 = fopen(flight_filename2, "rb+"); // Create file +// if (storage_file_2 == NULL) +// { +// err = errno; +// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) +// fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); +// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ +// +// // TODO: check errno values +// +// usleep(1 * 1000); // Sleep for 1 millisecond before trying again +// continue; +// } +// +// break; +// } +// +// if (storage_file_2 == NULL) +// { +// err = errno; +// pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully +// } +// +// active_storage_file = storage_file_2; /* Set Base time to current system time */ - if (clock_gettime(CLOCK_REALTIME, base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? + if (clock_gettime(CLOCK_REALTIME, &base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -390,7 +463,7 @@ void *logging_main(void *arg) } } - err = state_read_lock(state); + err = state_read_lock(state); // Should this be before ??? if (err) { err = errno; @@ -412,9 +485,8 @@ void *logging_main(void *arg) err = state_unlock(state); if (err) { - err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error releasing read lock: %d\n", err); + fprintf(stderr, "Error during state_unlock: %d\n", err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } @@ -433,8 +505,8 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ /* Generate log file name for extraction file system */ - int max_extraction_log_file_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_LANDED_FS "/flog_boot"); - snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number); + int max_extraction_log_file_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog_boot"); + snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number, 1); /* Open extraction log file */ for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. @@ -499,6 +571,13 @@ void *logging_main(void *arg) } err = state_set_flightstate(state, STATE_IDLE); // TODO: error handling + if (err < 0) + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error during state_set_flightstate: %d\n", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + } } } @@ -520,7 +599,7 @@ void *logging_main(void *arg) } -void teardown(FILE *flight_log_1, FILE* flight_log_2, FILE* extraction_file_ptr) +void teardown(FILE *flight_log_1, FILE* flight_log_2, FILE* extraction_log) { int err; if (fclose(flight_log_1) != 0) @@ -539,7 +618,7 @@ void teardown(FILE *flight_log_1, FILE* flight_log_2, FILE* extraction_file_ptr) #endif } - if (fclose(extraction_file_ptr) != 0) + if (fclose(extraction_log) != 0) { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) From 5ad420c4ef0f5112fe6c5a178fa68654b4ff0ae4 Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 10 Mar 2025 19:04:23 -0400 Subject: [PATCH 08/16] Resolved merge conflict in collection.c --- telemetry/src/collection/collection.c | 51 ++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/telemetry/src/collection/collection.c b/telemetry/src/collection/collection.c index 26124a5..a6f5945 100644 --- a/telemetry/src/collection/collection.c +++ b/telemetry/src/collection/collection.c @@ -5,7 +5,6 @@ #include #include - #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) #include #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ @@ -226,3 +225,53 @@ static uint32_t ms_since(struct timespec *start) { return diff.tv_sec * 1000 + (diff.tv_nsec / 1e6); } + +#include +#include +#include + +#define MAX_TIME 30 +#define FILENAME "test.txt" + +enum CurrentBuffer { + PING, + PONG +}; + +typedef struct buffer +{ + char *filename; + int* fd; + enum CurrentBuffer curr; +} buffer_t; + +void init(buffer_t *buff){ + buff->filename = FILENAME; + buff->fd = open(buff->filename); +} + +int swap_buffer(buffer_t *buff) +{ + int ret; + if (buff->curr == PING) + { + buff->curr = PONG; + ret = 0; + } + else if (buff->curr == PONG) + { + buff->curr = PING; + ret = 0; + } + else + { + /* Undefined */ + ret = -1; + } + + return ret; +} + +int check_if_time_passed(int *fd, int time_sec){ + +} From cb125a19625f2969d5a82f7467408adf353b420b Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 17 Mar 2025 18:40:31 -0400 Subject: [PATCH 09/16] Fixed some small typos and removed commented out code. --- telemetry/src/logging/logging.c | 130 ++------------------------------ 1 file changed, 6 insertions(+), 124 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 3514e85..fabddca 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -123,7 +123,7 @@ int switch_active_log_file(FILE **active_storage_file, FILE **storage_file_1, FI { for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. { - *storage_file_2 = fopen(flight_filename2, "rb+"); // Create file + *storage_file_2 = fopen(*flight_filename2, "rb+"); // Create file if (*storage_file_2 == NULL) { err = errno; @@ -277,8 +277,6 @@ void *logging_main(void *arg) //Save the time the file was last modified base_timespec = (struct timespec){file_info.st_mtime, 0}; - // base_timespec.tv_sec = file_info.st_mtime; - // base_timespec.tv_nsec = 0; /* Infinite loop to handle states */ for (;;) @@ -293,16 +291,6 @@ void *logging_main(void *arg) // TODO: figure out fail conditions } -// err = fstat(fileno(active_storage_file), &file_info); -// if (err) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error using fstat: %d\n", err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// fclose(active_storage_file); -// } - switch (flight_state) { case STATE_IDLE: @@ -311,67 +299,6 @@ void *logging_main(void *arg) // Switch between files every 30 seconds /* Store current system time in new_timespec */ -// if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error during clock_gettime: %d\n", err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// } -// -// double time_diff = timespec_diff(&new_timespec, &base_timespec); -// if (time_diff < 0) -// { -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// } -// -// if (time_diff >= 30.0) -// { -// if (active_storage_file == storage_file_1) -// { -// /* Create new log file */ -// for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. -// { -// storage_file_2 = fopen(flight_filename2, "rb+"); // Create file -// if (storage_file_2 == NULL) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// -// // TODO: check errno values -// usleep(1 * 1000); // Sleep for 1 millisecond before trying again -// continue; -// } -// -// break; -// } -// -// if (storage_file_2 == NULL) -// { -// err = errno; -// pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully -// } -// -// active_storage_file = storage_file_2; -// -// /* Store current system time as the new base time */ -// if (clock_gettime(CLOCK_REALTIME, &base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error during clock_gettime: %d\n", err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// } -// } -// else if (active_storage_file == storage_file_2) -// { -// active_storage_file = storage_file_1; -// } -// } case STATE_AIRBORNE: { @@ -388,12 +315,6 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - /* Log data */ - - // Sample logging - // uint8_t sample_buf[1] = {1}; - // written = fwrite(sample_buf, 1, 1, active_storage_file); - /* Store current system time as new_timespec */ if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { @@ -424,35 +345,6 @@ void *logging_main(void *arg) pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully } -// /* Create new log file */ -// for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. -// { -// // storage_file_2 = open(flight_filename2, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file -// storage_file_2 = fopen(flight_filename2, "rb+"); // Create file -// if (storage_file_2 == NULL) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// -// // TODO: check errno values -// -// usleep(1 * 1000); // Sleep for 1 millisecond before trying again -// continue; -// } -// -// break; -// } -// -// if (storage_file_2 == NULL) -// { -// err = errno; -// pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully -// } -// -// active_storage_file = storage_file_2; - /* Set Base time to current system time */ if (clock_gettime(CLOCK_REALTIME, &base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { @@ -472,6 +364,8 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } + /* Log data */ + written = fwrite(&state->data, sizeof(state->data), 1, active_storage_file); #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logged %u bytes\n", written * sizeof(state->data)); @@ -577,26 +471,14 @@ void *logging_main(void *arg) fprintf(stderr, "Error during state_set_flightstate: %d\n", err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - } } } -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - if (close(active_storage_file) != 0) - { - err = errno; - fprintf(stderr, "Failed to close flight logfile handle: %d\n", err); - } -#else - close(active_storage_file); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - pthread_exit(err_to_ptr(err)); - - -/* Teardown */ - teardown(storage_file_1, storage_file_2, extract_storage_file) + /* Teardown */ + teardown(storage_file_1, storage_file_2, extract_storage_file); + pthread_exit(err_to_ptr(err)); } void teardown(FILE *flight_log_1, FILE* flight_log_2, FILE* extraction_log) From 7a53fe9d7f3c7ec089b61c0d527a74724473ceac Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 17 Mar 2025 18:40:52 -0400 Subject: [PATCH 10/16] Updated to not track .vscode settings --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d30ea28..fb65ae5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /Kconfig Make.dep .built +.vscode/ \ No newline at end of file From 4481affcadd2e59925f4c8ba2a87269d3b9f5a0c Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 22 Mar 2025 17:39:18 -0400 Subject: [PATCH 11/16] "Moved functions bodies to below logging_main, put declarations above. Removed pseudocode, some redundant commented code, and teardown function as it wasn't really needed." --- telemetry/src/logging/logging.c | 407 +++++++++++++------------------- 1 file changed, 160 insertions(+), 247 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 3514e85..23c9890 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -34,146 +34,12 @@ #define NUM_TIMES_TRY_OPEN 3 -/* - * Logging Pseudocode: - * - * Find previous max boot number - * Create file names with boot number that is max boot number + 1 - * Open file 1 - * Set the active file to file 1 - * Get base time to the last modification time of file 1 (would be creation time) - * - * Enter loop: - * Get flight state - * If in IDLE state: Want to switch between two files every 30 seconds until launch - * Get the current time - * If current time - base time >= 30 seconds: - * Switch to other file - * If active file == file 1: - * Open file 2 - * Switch active file to file 2 - * Else if active file == file 2: - * Switch active file to file 1 - - * Else if in AIRBORNE state: - * Wait for data to change - * Log data to active file - * Set new_timespec to current system time - * - * - * Else if in LANDED state: - * Create file name for extraction file based on previous max boot number - * Open extraction file - * Copy from the active file to the extraction file - * Close extraction file - * Go to IDLE state - * - * Teardown - * Close files - * Exit thread - */ +// Private Functions -int find_max_boot_number(char *file){ - DIR *directory_pointer = opendir("./"); - struct dirent *entry; - - int max_boot_number = 0; - - if (directory_pointer != NULL) - { - while ((entry = readdir(directory_pointer)) != NULL) - { - if (strstr(entry->d_name, file) != NULL) - { - // Ex.) find /log/elog in /log/elog2. Index should be 8 to get number 2 - int index = strlen(file); - char char_num = entry->d_name[index]; - if (!isdigit(char_num)) - { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Number after logging file does not exist (%s)\n", file); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - return -1; - } - - int boot_number = char_num - '0'; // Convert from character to int using ASCII values - if (boot_number > max_boot_number) - { - max_boot_number = boot_number; - } - } - } - - (void)closedir(directory_pointer); - return max_boot_number; - } - else - { - perror("Couldn't open the directory: "); - return -1; - } -} - -int switch_active_log_file(FILE **active_storage_file, FILE **storage_file_1, FILE **storage_file_2, char **flight_filename2) -{ - int err; - if (*active_storage_file == *storage_file_1) - { - if (*storage_file_2 == NULL) - { - for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. - { - *storage_file_2 = fopen(flight_filename2, "rb+"); // Create file - if (*storage_file_2 == NULL) - { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 2 '%s': %d\n", *flight_filename2, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - - // TODO: check errno values - usleep(1 * 1000); // Sleep for 1 millisecond before trying again - continue; - } - - break; - } - - if (*storage_file_2 == NULL) - { - return -1; - } - - *active_storage_file = *storage_file_2; - } - - else - { - *active_storage_file = *storage_file_1; - } - } - - // If file_2 is currently active, that means file_1 was opened successfully, so just switch the pointer - else if (*active_storage_file == *storage_file_2) - { - if (*storage_file_1 == NULL) - { - return -1; - } - - *active_storage_file = *storage_file_1; - } - - return 0; -} - -/* - * Returns double time difference between two timespec structs - */ -double timespec_diff(struct timespec *end, struct timespec *start) -{ - return (end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec) / 1e9; -} +static int find_max_boot_number(char *file); +static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE *storage_file_2, char *flight_filename2); +static double timespec_diff(struct timespec *new_time, struct timespec *old_time); +static int try_open_file(FILE **file_to_open, char *filename, char *open_option); /* * Logging thread which runs to log data to the SD card. @@ -277,8 +143,6 @@ void *logging_main(void *arg) //Save the time the file was last modified base_timespec = (struct timespec){file_info.st_mtime, 0}; - // base_timespec.tv_sec = file_info.st_mtime; - // base_timespec.tv_nsec = 0; /* Infinite loop to handle states */ for (;;) @@ -293,16 +157,6 @@ void *logging_main(void *arg) // TODO: figure out fail conditions } -// err = fstat(fileno(active_storage_file), &file_info); -// if (err) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error using fstat: %d\n", err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// fclose(active_storage_file); -// } - switch (flight_state) { case STATE_IDLE: @@ -310,75 +164,6 @@ void *logging_main(void *arg) // Switch between files every 30 seconds - /* Store current system time in new_timespec */ -// if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error during clock_gettime: %d\n", err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// } -// -// double time_diff = timespec_diff(&new_timespec, &base_timespec); -// if (time_diff < 0) -// { -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// } -// -// if (time_diff >= 30.0) -// { -// if (active_storage_file == storage_file_1) -// { -// /* Create new log file */ -// for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. -// { -// storage_file_2 = fopen(flight_filename2, "rb+"); // Create file -// if (storage_file_2 == NULL) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// -// // TODO: check errno values -// usleep(1 * 1000); // Sleep for 1 millisecond before trying again -// continue; -// } -// -// break; -// } -// -// if (storage_file_2 == NULL) -// { -// err = errno; -// pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully -// } -// -// active_storage_file = storage_file_2; -// -// /* Store current system time as the new base time */ -// if (clock_gettime(CLOCK_REALTIME, &base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error during clock_gettime: %d\n", err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// } -// } -// else if (active_storage_file == storage_file_2) -// { -// active_storage_file = storage_file_1; -// } -// } - - case STATE_AIRBORNE: - { - /* Infinite loop to log data */ - - /* Wait for the data to have a change */ - err = state_wait_for_change(state, &version); if (err) { @@ -388,12 +173,6 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - /* Log data */ - - // Sample logging - // uint8_t sample_buf[1] = {1}; - // written = fwrite(sample_buf, 1, 1, active_storage_file); - /* Store current system time as new_timespec */ if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { @@ -582,47 +361,181 @@ void *logging_main(void *arg) } } + /* Close files that may be open */ + if (fclose(storage_file_1) != 0) + { + err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - if (close(active_storage_file) != 0) + fprintf(stderr, "Failed to close flight logfile 1 handle: %d\n", err); +#endif + } + + if (fclose(storage_file_2) != 0) { err = errno; - fprintf(stderr, "Failed to close flight logfile handle: %d\n", err); +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Failed to close flight logfile 2 handle: %d\n", err); +#endif } -#else - close(active_storage_file); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + pthread_exit(err_to_ptr(err)); +} + -/* Teardown */ - teardown(storage_file_1, storage_file_2, extract_storage_file) +/****************************************************/ +/* Helper Functions */ +/****************************************************/ +/** + * Attempt to open file given filename and flag option multiple times. Once opened, update active file pointer. + * + * @param active_file_pointer The pointer to the file to update + * @param filename The file name of the file to open + * @param open_option The string option passed to fopen (r, rb, rb+, etc) + * @return 0 if succesful, else error from errno + */ +static int try_open_file(FILE** active_file_pointer, char* filename, char* open_option){ + int err = 0; + for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. + { + *active_file_pointer = fopen(filename, open_option); + if (*active_file_pointer == NULL) + { + err = errno; +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error (Attempt %d) opening '%s' file: %d\n", i, filename, err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + + // TODO: check errno values + usleep(1 * 1000); // Sleep for 1 millisecond before trying again + } + else + { + break; + } + } + + return err; } -void teardown(FILE *flight_log_1, FILE* flight_log_2, FILE* extraction_log) +/** + * Find max boot number of logging files that already exist + * + * @param filename The format string name that will be checked + * @return The maximum boot number found of previous files, -1 if error + **/ +static int find_max_boot_number(char *filename) { - int err; - if (fclose(flight_log_1) != 0) + int max_boot_number = 0; + + DIR *directory_pointer = opendir("./"); + if (directory_pointer == NULL) { - err = errno; + perror("Couldn't open the directory: "); + return -1; + } + + struct dirent *entry; + while ((entry = readdir(directory_pointer)) != NULL) + { + if (strstr(entry->d_name, filename) != NULL) + { + int boot_number, file_number; + int vars_filled = sscanf(filename, FLIGHT_FNAME_FMT, &boot_number, &file_number); + + if (vars_filled != 2) + { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Failed to close flight logfile 1 handle: %d\n", err); -#endif + fprintf(stderr, "Error during sscanf: 2 values not filled"); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + } + + if (boot_number > max_boot_number) + { + max_boot_number = boot_number; + } + } } - if (fclose(flight_log_2) != 0) + (void)closedir(directory_pointer); + return max_boot_number; +} + +/** + * Switch the active file pointer for the ping pong buffer + * + * @param active_storage_file The active log file pointer + * @param storage_file_1 The pointer to the first log file + * @param storage_file_2 The pointer to the second log file + * @param flight_filename2 The name of the second log file + * @return 0 if succesful, -1 on error + **/ +static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE *storage_file_2, char *flight_filename2) +{ + int err = 0; + + /* Make sure we aren't dereferencing null pointer later */ + if (*active_storage_file == NULL) { - err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Failed to close flight logfile 2 handle: %d\n", err); -#endif + fprintf(stderr, "Error in switch_active_log_file: active_storage_file is NULL"); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + return -1; + } + + if (*active_storage_file == storage_file_1) + { + if (storage_file_2 != NULL){ + *active_storage_file = storage_file_2; + return err; + } + + /* If reach here, file 2 is not opened yet, so open it*/ + err = try_open_file(&storage_file_2, flight_filename2, "rb+"); + if (err < 0 || storage_file_2 == NULL) + { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Error (%d) trying to open %s", err, flight_filename2); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + return -1; + } + + *active_storage_file = storage_file_2; } - if (fclose(extraction_log) != 0) + // If file_2 is currently active, that means file_1 was opened successfully, so just switch the pointer + else if (*active_storage_file == storage_file_2) + { + if (storage_file_1 == NULL) + { + return -1; + } + + *active_storage_file = storage_file_1; + } + + /* Roll active log file pointer back to beginning */ + err = fseek(*active_storage_file, 0, SEEK_SET); + if (err) { - err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Failed to close extraction logfile handle: %d\n", err); -#endif + fprintf(stderr, "Couldn't seek active file back to start: %d", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } + + return err; } + + +/** + * Returns double time difference between two timespec structs + * + * @param new_time The newer (larger) time + * @param old_time The older (smaller) time + * @return The difference between the two times + **/ +static double timespec_diff(struct timespec *new_time, struct timespec *old_time) +{ + return (new_time->tv_sec - old_time->tv_sec) + (new_time->tv_nsec - old_time->tv_nsec) / 1e9; +} \ No newline at end of file From d8e618aff6b3cf28fd7baadf70eab54135c3330e Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 22 Mar 2025 17:42:31 -0400 Subject: [PATCH 12/16] Made helper function try_open_file to simplify code. Tweaked error handling messages, comments, and formatting. Also fixed some typos. --- telemetry/src/logging/logging.c | 134 +++++++++----------------------- 1 file changed, 36 insertions(+), 98 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 23c9890..97605e4 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -55,15 +55,15 @@ void *logging_main(void *arg) char flight_filename2[sizeof(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS) + MAX_FILENAME]; char land_filename[sizeof(CONFIG_INSPACE_TELEMETRY_LANDED_FS) + MAX_FILENAME]; - FILE *storage_file_1 = NULL; // File pointer for first logging file - FILE *storage_file_2 = NULL; // File pointer for second logging file - FILE *active_storage_file = NULL; // File pointer for active logging file + FILE *storage_file_1 = NULL; // File pointer for first logging file + FILE *storage_file_2 = NULL; // File pointer for second logging file + FILE *active_storage_file = NULL; // File pointer for active logging file - FILE *extract_storage_file; // File pointer for extraction logging file + FILE *extract_storage_file; // File pointer for extraction logging file - struct stat file_info; // Stat struct to hold fstat return - struct timespec base_timespec; // Time that file was last modified - struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed + struct stat file_info; // Stat struct to hold fstat return + struct timespec base_timespec; // Time that file was last modified + struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logging thread started.\n"); @@ -71,7 +71,7 @@ void *logging_main(void *arg) /* Generate flight log file names using the boot number */ - int max_flight_log_boot_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/elog_boot"); + int max_flight_log_boot_number = find_max_boot_number(EXTR_FNAME_FMT); if (max_flight_log_boot_number < 0) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -80,7 +80,7 @@ void *logging_main(void *arg) } snprintf(flight_filename1, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 1); - snprintf(flight_filename2, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 2); + snprintf(flight_filename2, sizeof(flight_filename2), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 2); if (strlen(flight_filename1) > MAX_FILENAME) // Check log 1 filename length { @@ -95,28 +95,13 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. - { - storage_file_1 = fopen(flight_filename1, "rb+"); // Create file for reading and writing - if (storage_file_1 == NULL) - { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 1 (Attempt %d)'%s': %d\n", i, flight_filename1, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - - //TODO: check errno values (if needed) - } - - usleep(1 * 1000); // Sleep for 1 millisecond before trying again - } - - if (storage_file_1 == NULL) + err = try_open_file(&storage_file_1, flight_filename1, "rb+"); + if (err < 0 || storage_file_1 == NULL) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Error opening log file 1 (%s): %d\n", flight_filename1, err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - pthred_exit(err_to_ptr(err)); // TODO: fail more gracefully + pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully } active_storage_file = storage_file_1; @@ -193,55 +178,25 @@ void *logging_main(void *arg) if (time_diff >= 30.0) { // Switch active log file - err = switch_active_log_file(&active_storage_file, &storage_file_1, &storage_file_2, &flight_filename2); + err = switch_active_log_file(&active_storage_file, storage_file_1, storage_file_2, flight_filename2); if (err < 0) { + err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Error switching active log file: %d\n", err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - err = errno; pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully } -// /* Create new log file */ -// for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. -// { -// // storage_file_2 = open(flight_filename2, O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Create file -// storage_file_2 = fopen(flight_filename2, "rb+"); // Create file -// if (storage_file_2 == NULL) -// { -// err = errno; -// #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) -// fprintf(stderr, "Error opening log file 2 '%s': %d\n", flight_filename2, err); -// #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ -// -// // TODO: check errno values -// -// usleep(1 * 1000); // Sleep for 1 millisecond before trying again -// continue; -// } -// -// break; -// } -// -// if (storage_file_2 == NULL) -// { -// err = errno; -// pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully -// } -// -// active_storage_file = storage_file_2; - - /* Set Base time to current system time */ - if (clock_gettime(CLOCK_REALTIME, &base_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? - { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during clock_gettime: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - } + /* Set Base time to current time to reset*/ + base_timespec = new_timespec; } + case STATE_AIRBORNE: + { + /* Infinite loop to log data */ + + /* Wait for the data to have a change */ err = state_read_lock(state); // Should this be before ??? if (err) { @@ -251,6 +206,7 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } + /* Log data to active log file*/ written = fwrite(&state->data, sizeof(state->data), 1, active_storage_file); #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) printf("Logged %u bytes\n", written * sizeof(state->data)); @@ -284,30 +240,11 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ /* Generate log file name for extraction file system */ - int max_extraction_log_file_number = find_max_boot_number(CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog_boot"); - snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number, 1); + int max_extraction_log_file_number = find_max_boot_number(EXTR_FNAME_FMT); + snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number + 1, 1); - /* Open extraction log file */ - for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. - { - extract_storage_file = fopen(land_filename, "wb"); - if (extract_storage_file == NULL) - { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error (Attempt %d) opening the extraction log file '%s': %d\n", i, land_filename, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - - // TODO: check errno values - usleep(1 * 1000); // Sleep for 1 millisecond before trying again - } - else - { - break; - } - } - - if (extract_storage_file == NULL) + err = try_open_file(&extract_storage_file, land_filename, "wb"); + if (err < 0 || extract_storage_file == NULL) { // If reach here, all attempts to open log file have failed, fatal error err = errno; @@ -318,10 +255,12 @@ void *logging_main(void *arg) } /* Roll power-safe log file pointer back to beginning */ - err = fseek(active_storage_file, 0, SEEK_SET); // TODO: handle error + err = fseek(active_storage_file, 0, SEEK_SET); if (err) { - /* Handle Error */ +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "Couldn't seek active file back to start: %d", err); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } /* Copy from one to the other using a buffer */ @@ -335,12 +274,8 @@ void *logging_main(void *arg) break; nbytes = sizeof(buf) * fwrite(buf, nbytes, 1, extract_storage_file); } - - /* Now that logs are copied to FAT partition, move back to the idle state - * for another go. - * flight_state = STATE_IDLE; - */ - + + /* Once done copying, close extraction file */ if (fclose(extract_storage_file) != 0) { err = errno; @@ -349,7 +284,10 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - err = state_set_flightstate(state, STATE_IDLE); // TODO: error handling + /* Now that logs are copied to FAT partition, move back to the idle state for another go. */ + flight_state = STATE_IDLE; + + err = state_set_flightstate(state, STATE_IDLE); if (err < 0) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) From d2adf6eedbbae89c4adce61dd72c4af7c6c8e2ac Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Sat, 29 Mar 2025 12:51:59 -0400 Subject: [PATCH 13/16] Fixed how max boot number found, now looks in /tmp folder. Also used double pointer to fix how files were switched. Put testing print code in debug conditionals. Also, removed some testing code. --- telemetry/src/logging/logging.c | 98 +++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 97605e4..86f24fa 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -20,11 +20,11 @@ /* The format for flight log file names */ -#define FLIGHT_FNAME_FMT CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "/flog_boot%d_%d.bin" +#define FLIGHT_FNAME_FMT CONFIG_INSPACE_TELEMETRY_FLIGHT_FS "flog_boot%d_%d.bin" /* The format for extraction log file names */ -#define EXTR_FNAME_FMT CONFIG_INSPACE_TELEMETRY_LANDED_FS "/elog_boot%d_%d.bin" +#define EXTR_FNAME_FMT CONFIG_INSPACE_TELEMETRY_LANDED_FS "elog_boot%d_%d.bin" /* Cast an error to a void pointer */ @@ -36,8 +36,8 @@ // Private Functions -static int find_max_boot_number(char *file); -static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE *storage_file_2, char *flight_filename2); +static int find_max_boot_number(); +static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE **storage_file_2, char *flight_filename2); static double timespec_diff(struct timespec *new_time, struct timespec *old_time); static int try_open_file(FILE **file_to_open, char *filename, char *open_option); @@ -71,7 +71,9 @@ void *logging_main(void *arg) /* Generate flight log file names using the boot number */ - int max_flight_log_boot_number = find_max_boot_number(EXTR_FNAME_FMT); + int max_flight_log_boot_number = find_max_boot_number(); + printf("Previous max boot number: %d\n", max_flight_log_boot_number); + if (max_flight_log_boot_number < 0) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -82,6 +84,11 @@ void *logging_main(void *arg) snprintf(flight_filename1, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 1); snprintf(flight_filename2, sizeof(flight_filename2), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 2); +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + printf("File 1 name: %s\n", flight_filename1); + printf("File 2 name: %s\n", flight_filename2); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + if (strlen(flight_filename1) > MAX_FILENAME) // Check log 1 filename length { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -95,7 +102,7 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } - err = try_open_file(&storage_file_1, flight_filename1, "rb+"); + err = try_open_file(&storage_file_1, flight_filename1, "wb+"); if (err < 0 || storage_file_1 == NULL) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -166,6 +173,9 @@ void *logging_main(void *arg) fprintf(stderr, "Error during clock_gettime: %d\n", err); #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ } +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + printf("Time: %d:%ld\n", new_timespec.tv_sec, new_timespec.tv_nsec); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ double time_diff = timespec_diff(&new_timespec, &base_timespec); if (time_diff < 0) @@ -177,8 +187,12 @@ void *logging_main(void *arg) if (time_diff >= 30.0) { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + printf("30 seconds passed\n"); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + // Switch active log file - err = switch_active_log_file(&active_storage_file, storage_file_1, storage_file_2, flight_filename2); + err = switch_active_log_file(&active_storage_file, storage_file_1, &storage_file_2, flight_filename2); if (err < 0) { err = errno; @@ -187,6 +201,26 @@ void *logging_main(void *arg) #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully } + +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + if (active_storage_file == storage_file_1) + { + printf("File 1 active\n\n"); + } + else if (active_storage_file == storage_file_2) + { + printf("File 2 active\n\n"); + } + else if (active_storage_file == NULL) + { + printf("ERROR: Active file is NULL\n\n"); + } + else + { + printf("ERROR: active file is neither\n\n"); + } +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + /* Set Base time to current time to reset*/ base_timespec = new_timespec; @@ -243,7 +277,7 @@ void *logging_main(void *arg) int max_extraction_log_file_number = find_max_boot_number(EXTR_FNAME_FMT); snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number + 1, 1); - err = try_open_file(&extract_storage_file, land_filename, "wb"); + err = try_open_file(&extract_storage_file, land_filename, "wb+"); if (err < 0 || extract_storage_file == NULL) { // If reach here, all attempts to open log file have failed, fatal error @@ -333,12 +367,12 @@ void *logging_main(void *arg) * @param open_option The string option passed to fopen (r, rb, rb+, etc) * @return 0 if succesful, else error from errno */ -static int try_open_file(FILE** active_file_pointer, char* filename, char* open_option){ +static int try_open_file(FILE** file_pointer, char* filename, char* open_option){ int err = 0; for (int i = 0; i < NUM_TIMES_TRY_OPEN; i++) // Matteo recomendeded trying multiple times, in case singular one fails. { - *active_file_pointer = fopen(filename, open_option); - if (*active_file_pointer == NULL) + *file_pointer = fopen(filename, open_option); + if (*file_pointer == NULL) { err = errno; #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) @@ -350,6 +384,9 @@ static int try_open_file(FILE** active_file_pointer, char* filename, char* open_ } else { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + printf("\nOpened File: %s\n\n", filename); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ break; } } @@ -360,35 +397,25 @@ static int try_open_file(FILE** active_file_pointer, char* filename, char* open_ /** * Find max boot number of logging files that already exist * - * @param filename The format string name that will be checked * @return The maximum boot number found of previous files, -1 if error **/ -static int find_max_boot_number(char *filename) +static int find_max_boot_number() { - int max_boot_number = 0; - - DIR *directory_pointer = opendir("./"); + + DIR *directory_pointer = opendir("/tmp"); if (directory_pointer == NULL) { perror("Couldn't open the directory: "); return -1; } + int max_boot_number = 0, boot_number = 0, file_number = 0; + struct dirent *entry; while ((entry = readdir(directory_pointer)) != NULL) { - if (strstr(entry->d_name, filename) != NULL) + if (sscanf(entry->d_name, "flog_boot%d_%d.bin", &boot_number, &file_number) == 2) { - int boot_number, file_number; - int vars_filled = sscanf(filename, FLIGHT_FNAME_FMT, &boot_number, &file_number); - - if (vars_filled != 2) - { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during sscanf: 2 values not filled"); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - } - if (boot_number > max_boot_number) { max_boot_number = boot_number; @@ -409,7 +436,7 @@ static int find_max_boot_number(char *filename) * @param flight_filename2 The name of the second log file * @return 0 if succesful, -1 on error **/ -static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE *storage_file_2, char *flight_filename2) +static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE **storage_file_2, char *flight_filename2) { int err = 0; @@ -424,14 +451,14 @@ static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file if (*active_storage_file == storage_file_1) { - if (storage_file_2 != NULL){ - *active_storage_file = storage_file_2; + if (*storage_file_2 != NULL){ + *active_storage_file = *storage_file_2; return err; } /* If reach here, file 2 is not opened yet, so open it*/ - err = try_open_file(&storage_file_2, flight_filename2, "rb+"); - if (err < 0 || storage_file_2 == NULL) + err = try_open_file(storage_file_2, flight_filename2, "wb+"); + if (err < 0 || *storage_file_2 == NULL) { #if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) fprintf(stderr, "Error (%d) trying to open %s", err, flight_filename2); @@ -439,14 +466,17 @@ static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file return -1; } - *active_storage_file = storage_file_2; + *active_storage_file = *storage_file_2; } // If file_2 is currently active, that means file_1 was opened successfully, so just switch the pointer - else if (*active_storage_file == storage_file_2) + else if (*active_storage_file == *storage_file_2) { if (storage_file_1 == NULL) { +#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) + fprintf(stderr, "ERROR: storage_file_1 is NULL\n"); +#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ return -1; } From 24fe24615e0d8bb22e23e2ff9cf5fc2a27f90412 Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 31 Mar 2025 18:50:13 -0400 Subject: [PATCH 14/16] Made macro to replace ugly preprocessor checks all over the code that checks if in debug to print values. --- telemetry/src/logging/logging.c | 146 ++++++++++---------------------- 1 file changed, 46 insertions(+), 100 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index 86f24fa..afb39cc 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -34,7 +34,15 @@ #define NUM_TIMES_TRY_OPEN 3 -// Private Functions +/* Macro to print only if debug enabled */ + +#ifdef CONFIG_INSPACE_TELEMETRY_DEBUG + #define DEBUG_FPRINTF(...) fprintf(__VA_ARGS__); +#else + #define DEBUG_FPRINTF(...) +#endif + +// Private Functions static int find_max_boot_number(); static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE **storage_file_2, char *flight_filename2); @@ -65,49 +73,38 @@ void *logging_main(void *arg) struct timespec base_timespec; // Time that file was last modified struct timespec new_timespec; // Time to check against base_time to see if 30 seconds has passed -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - printf("Logging thread started.\n"); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stdout, "Logging thread started.\n"); /* Generate flight log file names using the boot number */ int max_flight_log_boot_number = find_max_boot_number(); - printf("Previous max boot number: %d\n", max_flight_log_boot_number); + DEBUG_FPRINTF(stdout, "Previous max boot number: %d\n", max_flight_log_boot_number); if (max_flight_log_boot_number < 0) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error finding max boot number: return (%d)\n", max_flight_log_boot_number); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error finding max boot number: return (%d)\n", max_flight_log_boot_number); } snprintf(flight_filename1, sizeof(flight_filename1), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 1); snprintf(flight_filename2, sizeof(flight_filename2), FLIGHT_FNAME_FMT, max_flight_log_boot_number + 1, 2); -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - printf("File 1 name: %s\n", flight_filename1); - printf("File 2 name: %s\n", flight_filename2); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stdout, "File 1 name: %s\n", flight_filename1); + DEBUG_FPRINTF(stdout, "File 2 name: %s\n", flight_filename2); if (strlen(flight_filename1) > MAX_FILENAME) // Check log 1 filename length { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename1, MAX_FILENAME); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Log file 1's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename1, MAX_FILENAME); } + if (strlen(flight_filename2) > MAX_FILENAME) // Check log 2 filename length { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Log file's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename2, MAX_FILENAME); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Log file 2's name (%s) is longer than the maximum size of characters (%d)\n", flight_filename2, MAX_FILENAME); } err = try_open_file(&storage_file_1, flight_filename1, "wb+"); if (err < 0 || storage_file_1 == NULL) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error opening log file 1 (%s): %d\n", flight_filename1, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error opening log file 1 (%s): %d\n", flight_filename1, err); pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully } @@ -117,9 +114,7 @@ void *logging_main(void *arg) if (fd < 0) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error using fileno: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error using fileno: %d\n", err); fclose(active_storage_file); } @@ -127,9 +122,7 @@ void *logging_main(void *arg) if (err) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error using fstat: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error using fstat: %d\n", err); fclose(active_storage_file); } @@ -142,9 +135,7 @@ void *logging_main(void *arg) err = state_get_flightstate(state, &flight_state); if (err) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error getting flight state: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error getting flight state: %d\n", err); fclose(active_storage_file); // TODO: figure out fail conditions } @@ -160,45 +151,33 @@ void *logging_main(void *arg) if (err) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during state_wait_for_change: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error during state_wait_for_change: %d\n", err); } /* Store current system time as new_timespec */ if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during clock_gettime: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error during clock_gettime: %d\n", err); } -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - printf("Time: %d:%ld\n", new_timespec.tv_sec, new_timespec.tv_nsec); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stdout, "Time: %d:%ld\n", new_timespec.tv_sec, new_timespec.tv_nsec); double time_diff = timespec_diff(&new_timespec, &base_timespec); if (time_diff < 0) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error during timespec_diff (Negative difference returned): %f\n", time_diff); } if (time_diff >= 30.0) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - printf("30 seconds passed\n"); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stdout, "30 seconds passed\n"); // Switch active log file err = switch_active_log_file(&active_storage_file, storage_file_1, &storage_file_2, flight_filename2); if (err < 0) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error switching active log file: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error switching active log file: %d\n", err); pthread_exit(err_to_ptr(err)); // TODO: fail more gracefully } @@ -221,7 +200,6 @@ void *logging_main(void *arg) } #endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - /* Set Base time to current time to reset*/ base_timespec = new_timespec; } @@ -235,16 +213,13 @@ void *logging_main(void *arg) if (err) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during state_read_lock: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error during state_read_lock: %d\n", err); } /* Log data to active log file*/ written = fwrite(&state->data, sizeof(state->data), 1, active_storage_file); -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - printf("Logged %u bytes\n", written * sizeof(state->data)); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stdout, "Logged %lu bytes\n", written * sizeof(state->data)); + if (written == 0) { // TODO: Handle error (might happen if file got too large, start @@ -254,9 +229,7 @@ void *logging_main(void *arg) err = state_unlock(state); if (err) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during state_unlock: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error during state_unlock: %d\n", err); } /* If we are in the idle state, only write the latest n seconds of data*/ @@ -269,9 +242,7 @@ void *logging_main(void *arg) case STATE_LANDED: { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - printf("Copying files to extraction file system.\n"); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stdout, "Copying files to extraction file system.\n"); /* Generate log file name for extraction file system */ int max_extraction_log_file_number = find_max_boot_number(EXTR_FNAME_FMT); @@ -282,9 +253,7 @@ void *logging_main(void *arg) { // If reach here, all attempts to open log file have failed, fatal error err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Couldn't open extraction log file '%s' with error: %d\n", land_filename, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Couldn't open extraction log file '%s' with error: %d\n", land_filename, err); pthread_exit(err_to_ptr(err)); } @@ -292,9 +261,7 @@ void *logging_main(void *arg) err = fseek(active_storage_file, 0, SEEK_SET); if (err) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Couldn't seek active file back to start: %d", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Couldn't seek active file back to start: %d", err); } /* Copy from one to the other using a buffer */ @@ -312,10 +279,8 @@ void *logging_main(void *arg) /* Once done copying, close extraction file */ if (fclose(extract_storage_file) != 0) { - err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Couldn't close extraction log file '%s' with error: %d\n", land_filename, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + err = errno; + DEBUG_FPRINTF(stderr, "Couldn't close extraction log file '%s' with error: %d\n", land_filename, err); } /* Now that logs are copied to FAT partition, move back to the idle state for another go. */ @@ -324,11 +289,8 @@ void *logging_main(void *arg) err = state_set_flightstate(state, STATE_IDLE); if (err < 0) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error during state_set_flightstate: %d\n", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ - } - + DEBUG_FPRINTF(stderr, "Error during state_set_flightstate: %d\n", err); + } } } } @@ -337,17 +299,13 @@ void *logging_main(void *arg) if (fclose(storage_file_1) != 0) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Failed to close flight logfile 1 handle: %d\n", err); -#endif + DEBUG_FPRINTF(stderr, "Failed to close flight logfile 1 handle: %d\n", err); } if (fclose(storage_file_2) != 0) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Failed to close flight logfile 2 handle: %d\n", err); -#endif + DEBUG_FPRINTF(stderr, "Failed to close flight logfile 2 handle: %d\n", err); } pthread_exit(err_to_ptr(err)); @@ -375,18 +333,14 @@ static int try_open_file(FILE** file_pointer, char* filename, char* open_option) if (*file_pointer == NULL) { err = errno; -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error (Attempt %d) opening '%s' file: %d\n", i, filename, err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error (Attempt %d) opening '%s' file: %d\n", i, filename, err); // TODO: check errno values usleep(1 * 1000); // Sleep for 1 millisecond before trying again } else { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - printf("\nOpened File: %s\n\n", filename); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stdout, "\nOpened File: %s\n\n", filename); break; } } @@ -443,9 +397,7 @@ static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file /* Make sure we aren't dereferencing null pointer later */ if (*active_storage_file == NULL) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error in switch_active_log_file: active_storage_file is NULL"); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error in switch_active_log_file: active_storage_file is NULL"); return -1; } @@ -460,9 +412,7 @@ static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file err = try_open_file(storage_file_2, flight_filename2, "wb+"); if (err < 0 || *storage_file_2 == NULL) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Error (%d) trying to open %s", err, flight_filename2); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Error (%d) trying to open %s", err, flight_filename2); return -1; } @@ -474,9 +424,7 @@ static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file { if (storage_file_1 == NULL) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "ERROR: storage_file_1 is NULL\n"); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "ERROR: storage_file_1 is NULL\n"); return -1; } @@ -487,9 +435,7 @@ static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file err = fseek(*active_storage_file, 0, SEEK_SET); if (err) { -#if defined(CONFIG_INSPACE_TELEMETRY_DEBUG) - fprintf(stderr, "Couldn't seek active file back to start: %d", err); -#endif /* defined(CONFIG_INSPACE_TELEMETRY_DEBUG) */ + DEBUG_FPRINTF(stderr, "Couldn't seek active file back to start: %d", err); } return err; From 0ea546f1ef9108ef1aa9cb746cd6773e1167a7bf Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 31 Mar 2025 18:57:12 -0400 Subject: [PATCH 15/16] find_max_boot_number now takes format string to distinguish between flight filenames and extraction filenames. --- telemetry/src/logging/logging.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index afb39cc..d2d26d6 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -44,7 +44,7 @@ // Private Functions -static int find_max_boot_number(); +static int find_max_boot_number(char* format_string); static int switch_active_log_file(FILE **active_storage_file, FILE *storage_file_1, FILE **storage_file_2, char *flight_filename2); static double timespec_diff(struct timespec *new_time, struct timespec *old_time); static int try_open_file(FILE **file_to_open, char *filename, char *open_option); @@ -77,7 +77,7 @@ void *logging_main(void *arg) /* Generate flight log file names using the boot number */ - int max_flight_log_boot_number = find_max_boot_number(); + int max_flight_log_boot_number = find_max_boot_number("flog_boot%d_%d.bin"); DEBUG_FPRINTF(stdout, "Previous max boot number: %d\n", max_flight_log_boot_number); if (max_flight_log_boot_number < 0) @@ -245,7 +245,7 @@ void *logging_main(void *arg) DEBUG_FPRINTF(stdout, "Copying files to extraction file system.\n"); /* Generate log file name for extraction file system */ - int max_extraction_log_file_number = find_max_boot_number(EXTR_FNAME_FMT); + int max_extraction_log_file_number = find_max_boot_number("elog_boot%d_%d.bin"); snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number + 1, 1); err = try_open_file(&extract_storage_file, land_filename, "wb+"); @@ -353,9 +353,8 @@ static int try_open_file(FILE** file_pointer, char* filename, char* open_option) * * @return The maximum boot number found of previous files, -1 if error **/ -static int find_max_boot_number() +static int find_max_boot_number(char* format_string) { - DIR *directory_pointer = opendir("/tmp"); if (directory_pointer == NULL) { @@ -368,7 +367,7 @@ static int find_max_boot_number() struct dirent *entry; while ((entry = readdir(directory_pointer)) != NULL) { - if (sscanf(entry->d_name, "flog_boot%d_%d.bin", &boot_number, &file_number) == 2) + if (sscanf(entry->d_name, format_string, &boot_number, &file_number) == 2) { if (boot_number > max_boot_number) { From 45aeccdea7cf59145fe01fa1c0fe7c7044aa3ac2 Mon Sep 17 00:00:00 2001 From: Justin Morrison Date: Mon, 31 Mar 2025 19:22:09 -0400 Subject: [PATCH 16/16] Minor cleanup --- telemetry/src/logging/logging.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/telemetry/src/logging/logging.c b/telemetry/src/logging/logging.c index d2d26d6..37255d4 100644 --- a/telemetry/src/logging/logging.c +++ b/telemetry/src/logging/logging.c @@ -76,7 +76,6 @@ void *logging_main(void *arg) DEBUG_FPRINTF(stdout, "Logging thread started.\n"); /* Generate flight log file names using the boot number */ - int max_flight_log_boot_number = find_max_boot_number("flog_boot%d_%d.bin"); DEBUG_FPRINTF(stdout, "Previous max boot number: %d\n", max_flight_log_boot_number); @@ -155,7 +154,7 @@ void *logging_main(void *arg) } /* Store current system time as new_timespec */ - if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) // TODO: Is CLOCK_REALTIME the correct option? + if (clock_gettime(CLOCK_REALTIME, &new_timespec) < 0) { err = errno; DEBUG_FPRINTF(stderr, "Error during clock_gettime: %d\n", err); @@ -222,8 +221,7 @@ void *logging_main(void *arg) if (written == 0) { - // TODO: Handle error (might happen if file got too large, start - // another file) + // TODO: Handle error (might happen if file got too large, start another file) } err = state_unlock(state); @@ -247,6 +245,7 @@ void *logging_main(void *arg) /* Generate log file name for extraction file system */ int max_extraction_log_file_number = find_max_boot_number("elog_boot%d_%d.bin"); snprintf(land_filename, sizeof(land_filename), EXTR_FNAME_FMT, max_extraction_log_file_number + 1, 1); + DEBUG_FPRINTF(stdout, "Extraction file name: %s\n", land_filename); err = try_open_file(&extract_storage_file, land_filename, "wb+"); if (err < 0 || extract_storage_file == NULL) @@ -334,8 +333,6 @@ static int try_open_file(FILE** file_pointer, char* filename, char* open_option) { err = errno; DEBUG_FPRINTF(stderr, "Error (Attempt %d) opening '%s' file: %d\n", i, filename, err); - - // TODO: check errno values usleep(1 * 1000); // Sleep for 1 millisecond before trying again } else @@ -351,7 +348,8 @@ static int try_open_file(FILE** file_pointer, char* filename, char* open_option) /** * Find max boot number of logging files that already exist * - * @return The maximum boot number found of previous files, -1 if error + * @param format_string The formatted string to sscanf to extract the boot number from. eg.) "flog_boot%d_%d.bin" + * @return The maximum boot number found of previous files, -1 if error **/ static int find_max_boot_number(char* format_string) {