I believe there's a simple way to use only n cells and a single dedicated bit pattern to achieve n/2 increase in durability.
The dedicated bit pattern (e.g. 0xffff) is a marker which indicates an unused cell, and in normal operation at most one cell at a time has this value:
uint16_t readWord (const uint16_t *address);
void writeWord (uint16_t *address, uint16_t value);
#define CELL_COUNT 42
#define BASE_ADDRESS 12
#define MARKER 0xffff // Best to use EEPROM default for this
static uint8_t curCell = 0;
static void wlInit (void)
{
for ( uint8_t ii = 0 ; ii < CELL_COUNT ; ii++ ) {
if ( readWord (BASE_ADDRESS + ii) != MARKER ) {
curCell = ii;
// No early return/break here to keep init() execution time
// constant. Could also check for corruption here by checking for
// > 1 cells with MARKER (see below).
}
}
// If we didn't find a non-marker cell we'll end up with curCell = 0
// per the initial value of curCell
}
static uint16_t wlRead (void)
{
return readWord (BASE_ADDRESS + curCell);
}
static void wlWrite (uint16_t value)
{
assert (value != MARKER); // Storing marker value is big no-no
uint8_t nextCell = (curCell + 1) % CELL_COUNT;
writeWord (BASE_ADDRESS + nextCell, value);
writeWord (BASE_ADDRESS + curCell, MARKER);
curCell = nextCell;
}
The same approach can be used with structured data provided a bit pattern can be reserved (either in a dedicated byte or from some other field that has a spare pattern).
This approach also has a useful property with respect to interrupted (e.g. power drop) writes: if there are ever two cells without the MARKER value an incomplete (i.e. corrupted) write has occurred. This seems useful, because e.g. the ATmega328P datasheet contains the following unclear and not-particularly-reassuring paragraph about using brown-out detection to avoid corruption:
Keep the AVR RESET active (low) during periods of insufficient power
supply voltage. This can be done by enabling the internal Brown-out
Detector (BOD). If the detection level of the internal BOD does not
match the needed detection level, an external low V CC reset
Protection circuit can be used. If a reset occurs while a write
operation is in progress, the write operation will be com- pleted
provided that the power supply voltage is sufficient.