From a2589c357365e669d5b09f8d794152f94c11f4d7 Mon Sep 17 00:00:00 2001 From: "tridge60@gmail.com" Date: Sun, 4 Sep 2011 06:39:57 +0000 Subject: [PATCH] AP_Var: added EEPROM wear levelling This adds a variable length dummy variable at the front of the EEPROM when we erase it, which has the effect of moving the location of any hot variables within the EEPROM. This should improve EEPROM life. Thanks to Mike for the implementation. Pair-Programmed-With: Mike Smith git-svn-id: https://arducopter.googlecode.com/svn/trunk@3234 f9c3cf11-9bcb-44bc-f272-b75c42450872 --- libraries/AP_Common/AP_Var.cpp | 13 ++++++++++++- libraries/AP_Common/AP_Var.h | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libraries/AP_Common/AP_Var.cpp b/libraries/AP_Common/AP_Var.cpp index 95b7016335..956f527a3a 100644 --- a/libraries/AP_Common/AP_Var.cpp +++ b/libraries/AP_Common/AP_Var.cpp @@ -593,6 +593,8 @@ bool AP_Var::_EEPROM_locate(bool allocate) // sentinel. // if (0 == _tail_sentinel) { + uint8_t pad_size; + debug("writing header"); EEPROM_header ee_header; @@ -601,8 +603,17 @@ bool AP_Var::_EEPROM_locate(bool allocate) ee_header.spare = 0; eeprom_write_block(&ee_header, (void *)0, sizeof(ee_header)); - + _tail_sentinel = sizeof(ee_header); + + // Write a variable-sized pad header with a reserved key value + // to help wear-level the EEPROM a bit. + pad_size = (((uint8_t)micros()) % k_size_max) + 1; // should be fairly random + var_header.key = k_key_pad; + var_header.size = pad_size - 1; + + eeprom_write_block(&var_header, (void *)_tail_sentinel, sizeof(var_header)); + _tail_sentinel += sizeof(var_header) + pad_size; } // Save the location we are going to insert at, and compute the new diff --git a/libraries/AP_Common/AP_Var.h b/libraries/AP_Common/AP_Var.h index 8cb493257a..6ed680d7ab 100644 --- a/libraries/AP_Common/AP_Var.h +++ b/libraries/AP_Common/AP_Var.h @@ -112,6 +112,10 @@ public: /// static const Key k_key_sentinel = 0xff; + /// Key assigned to the wear-balancing pad entry in EEPROM. + /// + static const Key k_key_pad = 0xfe; + /// A bitmask that removes any control bits from a key giving just the /// value. ///