Finding oldest entry in a circular buffer, taking integer overflow into
account
I'd like to store a series of log entries in a circular buffer in a Flash
memory device.
The flash device has no onboard wear levelling, so I need to handle it in
my logging code. A circular buffer would do this as part of the
implementation, but I'm having trouble with an integer overflow issue.
What I intend to do is partition the flash area into areas like this:
char index;
char checksum;
char logdata[512-(sizeof(char)*2))];
Index = 0xFF means "erased". So the ID can range from 0x00 to 0xFE (zero
to 254). That means the increment rule is:
id = (last_id + 1) % 255
When the flash starts out, it looks like this (showing IDs only):
FF FF FF FF FF
We pick the first empty block (index zero) and write in our first log entry:
00 FF FF FF FF
This continues until none of the entries are erased:
00 01 02 03 04
When we pick the lowest numbered block, erase it and overwrite with new data:
05 01 02 03 04
But when the 8-bit ID overflows, bad things happen:
FA FB FC FD FE
00 FB FC FD FE (OK)
01 FB FC FD FE (Not OK - should have overwritten "FB"!)
02 FB FC FD FE (Stuck writing the first block over and over)
Which means the first block is now being used for every single write, and
we're back in the "uneven writes" scenario I want to avoid. What I want to
do is find the oldest block, which in this case is "FB".
Here's the code I have at the moment (in Python):
buf = [0xFF]*5
for i in range(260):
note = ""
slot = None
# Find first erased slot
for x in range(len(buf)):
if buf[x] == 0xFF:
slot = x
break
if slot is None:
# No erased slots, find lowest numbered slot
n = 0xFF
for x in range(len(buf)):
if buf[x] < n:
n = buf[x]
slot = x
# Debug output
print ''.join(["%02X " % x for x in buf])
# Write new block
buf[slot] = i % 255
How can I handle the integer overflow case correctly?
No comments:
Post a Comment