在页可写扇区可擦除闪存中实现标准堆栈

Implementing a standard stack in a page-writable sector-erasable flash memory

我想在我的微控制器固件中实现一个简单的堆栈。 我想实现的堆栈就像 this,即标准的东西。

问题是我使用的闪存IC支持页面粒度的写入,但支持扇区粒度的擦除,就像任何其他NAND闪存一样,在闪存上写入一些数据之前,你应该擦除那部分。

总而言之,我擦除一个扇区并在其第一页上写入一些数据。为了重写那个页面的一个字节,我应该先擦除整个扇区。

在我的堆栈中,

|欧 |欧 |欧 |欧 |欧 | O |

我推送了一些数据:

|瓦 |瓦 |瓦 |欧 |欧 | O |

然后弹出其中一个:

|瓦 |瓦 |磷 |欧 |欧 | O |

现在我想再推一个数据。问题就出现在这里。如果像标准堆栈一样,我决定写入以前的数据并更改索引,我必须先删除整个扇区!因此我应该以编程方式解决这个问题。

有什么想法吗?

P.S:闪存映射为:16 Blocks -> Each Block = 16 Sectors -> Each Sector = 16 Pages -> Each Page = 256 Bytes

我有一个页面级别的写入命令,其中包含针对扇区和块的偏移和擦除命令。

好吧,如果你不想每次推送都写入整个扇区,你将不得不容忍堆栈中的一些旧数据:

|瓦 |瓦 |磷 |瓦 |欧 | O |

您需要在每个项目中至少保留一位,以便您区分有效和无效的项目。假设扇区擦除用 1 填充它,然后将有效位 1 保留在您写入的所有有效项中。然后,当您弹出该项目时,您可以通过写 仅一页 将其更改为 0,将其标记为无效。

由于您不能在此方案中重复使用物品槽位,因此您的堆栈将不断增长,直至内存尽头。这实际上就是你想要的,因为 NAND 闪存在它死之前只能写入这么多次,而且这个方案会在一定程度上分散写入。当您到达 space 的末尾时,您可以擦除并重写整个内容以消除所有空白。

您可能会遇到一长串无效项目,因此跳过它们可能需要扫描所有中间项目。您可以通过在每个项目中保留多于一位来解决此问题。当你写一个有效的项目时,你使用这些位来存储它之前的无效项目的数量,再加上 1。这让你可以快速跳回并在恒定时间内弹出。

然后,当您想要将某个项目标记为无效时,您可以将为此计数保留的位更改为全 0,同样只需写入一页即可。此零计数不能出现在有效项目中,因此它作为无效标记。