2

我想将一系列日志条目存储在闪存设备的循环缓冲区中。

闪存设备没有板载磨损均衡,所以我需要在我的日志代码中处理它。循环缓冲区将作为实现的一部分执行此操作,但我遇到了整数溢出问题。

我打算做的是将闪存区域划分为如下区域:

char index;
char checksum;
char logdata[512-(sizeof(char)*2))];

Index = 0xFF 表示“已擦除”。因此 ID 的范围可以从 0x00 到 0xFE(零到 254)。这意味着增量规则是:

id = (last_id + 1) % 255

当 flash 启动时,它看起来像这样(仅显示 ID):

FF FF FF FF FF

我们选择第一个空块(索引为零)并写入我们的第一个日志条目:

00 FF FF FF FF

这一直持续到没有条目被删除:

00 01 02 03 04

当我们选择编号最小的块时,将其擦除并用新数据覆盖:

05 01 02 03 04

但是当 8 位 ID 溢出时,坏事就发生了:

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)

这意味着现在每个写入都使用第一个块,我们又回到了我想避免的“不均匀写入”场景。我想做的是找到最旧的块,在这种情况下是“FB”。

这是我目前拥有的代码(在 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

如何正确处理整数溢出情况?

4

2 回答 2

0

该循环正在寻找编号最小的插槽。井00、01和02都小于FB。这就是为什么第一个插槽在第一次翻转后一直被重复使用的原因。

你需要更好的设计。也许保留一个始终引用下一个可用插槽的循环缓冲区索引。

于 2013-09-09T13:49:17.233 回答
0

我看到了两种可能的解决方法。

第一个为您的队列保留相同的容量,但要求容量必须小于 255。

我们的想法是完全按照你现在的样子写,但不是寻找最小的数字,而是首先寻找序列中的不连续性,即从一个单元格到下一个单元格的差异不是一个的点。以您的初始情况为例:

FA FB FC FD FE
00 FB FC FD FE  (discontinuous at fe->fa, use fa)
00 01 FC FD FE  (discontinuous at 00->fb, use fb)
00 01 02 FD FE  (discontinuous at 01->fc, use fc)

它需要小于 255 的原因是,一旦它变得那么大,就没有不连续性,因为每个周期这些数字将恰好环绕一次。

另一种方法是无论如何都简单地使用特殊标记ff来指示下一个空闲插槽。

它的工作方式是,每当您将记录写入条目时,您也会写入下一个条目,但带有ff标记。

然后,要查找下一个要填充的条目,您只需查找第一个ff. 在启动阶段,会有多个ff标记,您只需选择第一个,但一旦用尽,每次写入都会给您另一个:

ff ff ff ff ff ff
00 ff ff ff ff ff
00 01 ff ff ff ff
00 01 02 ff ff ff
00 01 02 03 ff ff
00 01 02 03 04 ff
ff 01 02 03 04 05
06 ff 02 03 04 05

这会将您的循环缓冲区容量减少一个,并导致读取次数是原始方案的两倍,因此我更喜欢上面的第一个方案以减少写入。

但是,如果您想要更大的缓冲区(超过 254 个元素),这是实现它的一种方法。

于 2015-01-21T07:23:40.820 回答