altos: Handle flight_log_max not being multiple of ao_storage_block
authorKeith Packard <keithp@keithp.com>
Tue, 9 Jun 2020 04:05:17 +0000 (21:05 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 9 Jun 2020 04:17:55 +0000 (21:17 -0700)
In this case, flight records start in the middle of an erase block, but
now end at the erase block before the next flight.

When checking for an empty log slot, the entire erase block containing
the start of the flight is checked to make sure it's clear, skipping
it if not.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/kernel/ao_log.c
src/kernel/ao_log.h
src/kernel/ao_log_gps.c

index c0a42b295938586cd9f968af2cdb2445ae28e373..f0816aeeeb07365836c29627ccd84ed10c275660 100644 (file)
@@ -111,6 +111,27 @@ ao_log_erase_mark(void)
        ao_config_put();
 }
 
+/* Position of first flight record in slot */
+static uint32_t
+ao_log_pos(uint8_t slot)
+{
+       return ((slot) * ao_config.flight_log_max);
+}
+
+/* Start of erase block containing first flight record */
+static uint32_t
+ao_log_pos_block_start(uint8_t slot)
+{
+       return ao_log_pos(slot) & ~(ao_storage_block - 1);
+}
+
+/* End of erase block containing last flight record */
+static uint32_t
+ao_log_pos_block_end(uint8_t slot)
+{
+       return ao_log_pos_block_start(slot + 1);
+}
+
 #ifndef AO_LOG_UNCOMMON
 /*
  * Common logging functions which depend on the type of the log data
@@ -159,30 +180,17 @@ ao_log_check_data(void)
        return 1;
 }
 
-uint8_t
-ao_log_check_clear(void)
-{
-       uint8_t *b = (uint8_t *) &ao_log_data;
-       uint8_t i;
-
-       for (i = 0; i < sizeof (ao_log_type); i++) {
-               if (*b++ != 0xff)
-                       return 0;
-       }
-       return 1;
-}
-
 int16_t
 ao_log_flight(uint8_t slot)
 {
+       if (ao_storage_is_erased(ao_log_pos_block_start(slot)))
+               return 0;
+
        if (!ao_storage_read(ao_log_pos(slot),
                             &ao_log_data,
                             sizeof (ao_log_type)))
                return -(int16_t) (slot + 1);
 
-       if (ao_log_check_clear())
-               return 0;
-
        if (!ao_log_check_data() || ao_log_data.type != AO_LOG_FLIGHT)
                return -(int16_t) (slot + 1);
 
@@ -196,12 +204,6 @@ ao_log_slots(void)
        return (uint8_t) (ao_storage_log_max / ao_config.flight_log_max);
 }
 
-uint32_t
-ao_log_pos(uint8_t slot)
-{
-       return ((slot) * ao_config.flight_log_max);
-}
-
 static int16_t
 ao_log_max_flight(void)
 {
@@ -222,33 +224,16 @@ ao_log_max_flight(void)
        return max_flight;
 }
 
-static void
+static uint8_t
 ao_log_erase(uint8_t slot) 
 {
-       uint32_t log_current_pos, log_end_pos;
+       uint32_t start_pos;
+       uint32_t end_pos;
 
        ao_log_erase_mark();
-       log_current_pos = ao_log_pos(slot);
-       log_end_pos = log_current_pos + ao_config.flight_log_max;
-       while (log_current_pos < log_end_pos) {
-               uint8_t i;
-               static uint8_t b;
-
-               /*
-                * Check to see if we've reached the end of
-                * the used memory to avoid re-erasing the same
-                * memory over and over again
-                */
-               for (i = 0; i < 16; i++) {
-                       if (ao_storage_read(log_current_pos + i, &b, 1))
-                               if (b != 0xff)
-                                       break;
-               }
-               if (i == 16)
-                       break;
-               ao_storage_erase(log_current_pos);
-               log_current_pos += ao_storage_block;
-       }
+       start_pos = ao_log_pos_block_start(slot);
+       end_pos = ao_log_pos_block_end(slot);
+       return ao_storage_erase(start_pos, end_pos - start_pos);
 }
 
 static void
@@ -298,12 +283,13 @@ ao_log_scan(void)
                log_slots = ao_log_slots();
                for (log_slot = 1; log_slot < log_slots; log_slot++) {
                        if (ao_log_flight(log_slot) != 0)
-                               ao_log_erase(log_slot);
+                               if (!ao_log_erase(log_slot))
+                                       printf("erase %d failed\n", log_slot);
                }
                ao_config_log_fix_append();
        }
        ao_log_current_pos = ao_log_pos(0);
-       ao_log_end_pos = ao_log_current_pos + ao_storage_log_max;
+       ao_log_end_pos = ao_log_pos_block_end(0);
 
        if (ao_flight_number) {
                uint32_t        full = ao_log_current_pos;
@@ -359,7 +345,7 @@ ao_log_scan(void)
        do {
                if (ao_log_flight(log_slot) == 0) {
                        ao_log_current_pos = ao_log_pos(log_slot);
-                       ao_log_end_pos = ao_log_current_pos + ao_config.flight_log_max;
+                       ao_log_end_pos = ao_log_pos_block_end(log_slot);
                        break;
                }
                if (++log_slot >= log_slots)
@@ -420,7 +406,12 @@ ao_log_list(void)
                        printf ("flight %d start %x end %x\n",
                                flight,
                                (uint16_t) (ao_log_pos(slot) >> 8),
-                               (uint16_t) (ao_log_pos(slot+1) >> 8));
+                               (uint16_t) (ao_log_pos_block_end(slot) >> 8));
+               else
+                       printf ("slot %d  start %x end %x\n",
+                               slot,
+                               (uint16_t) (ao_log_pos(slot) >> 8),
+                               (uint16_t) (ao_log_pos_block_end(slot) >> 8));
        }
        printf ("done\n");
 }
@@ -449,11 +440,13 @@ ao_log_delete(void)
 #if HAS_TRACKER
                                ao_tracker_erase_start(cmd_flight);
 #endif
-                               ao_log_erase(slot);
+                               if (ao_log_erase(slot))
+                                       puts("Erased");
+                               else
+                                       puts("Failed to erase");
 #if HAS_TRACKER
                                ao_tracker_erase_end();
 #endif
-                               puts("Erased");
                                return;
                        }
                }
index 1c0ba4e3cf8c766049e42b44aa2478b8160c6e35..8fe8b701c291a54af52c8e4864e824994d259ced 100644 (file)
@@ -96,10 +96,6 @@ ao_log(void);
 uint8_t
 ao_log_scan(void);
 
-/* Return the position of the start of the given log slot */
-uint32_t
-ao_log_pos(uint8_t slot);
-
 /* Start logging to eeprom */
 void
 ao_log_start(void);
index 7284932cf6f2c98d2558931ff3895964258179d2..bf326c1a7fb972b7e0d601adfaab767b806586a0 100644 (file)
@@ -84,14 +84,14 @@ ao_log_gps_tracking(uint16_t tick, struct ao_telemetry_satellite *gps_tracking_d
 int8_t
 ao_log_check(uint32_t pos)
 {
+       if (ao_storage_is_erased(pos & ~(ao_storage_block - 1)))
+               return 0;
+
        if (!ao_storage_read(pos,
                             &ao_log_data,
                             sizeof (struct ao_log_gps)))
                return AO_LOG_INVALID;
 
-       if (ao_log_check_clear())
-               return AO_LOG_EMPTY;
-
        if (!ao_log_check_data())
                return AO_LOG_INVALID;
        return AO_LOG_VALID;