问题描述
我想在我的微控制器固件中实现一个简单的堆栈。 我想要实现的堆栈类似于 this,即标准的东西。
问题是我使用的闪存 IC 支持页面粒度写入但扇区粒度用于擦除,就像任何其他 NAND 闪存一样,在闪存上写入一些数据之前,您应该擦除该部分。
>作为总结,我擦除了一个扇区并在其第一页上写入了一些数据。要重写该页的一个字节,我应该先擦除整个扇区。
在我的叠层,
|哦|哦|哦|哦|哦|哦|
我推送一些数据:
| W | W | W |哦|哦|哦|
然后弹出其中一个:
| W | W | P |哦|哦|哦|
现在我想推送另一个数据。问题出现在这里。如果就像标准堆栈一样,我决定在以前的数据上写入并更改索引,则必须先删除整个扇区!因此我应该以编程方式解决这个问题。
有什么想法吗?
P.S:闪存映射为:16 Blocks -> Each Block = 16 Sectors -> Each Sector = 16 Pages -> Each Page = 256 Bytes
我在页级有一个写入命令,其中包含针对扇区和块的偏移和擦除命令。
解决方法
好吧,如果你不想每次推送都写一个完整的扇区,你将不得不容忍堆栈中的一些旧数据:
| W | W | P | W |哦|哦|
您需要在每个项目中至少保留一位,以便区分有效和无效的项目。假设扇区擦除用 1 填充它,然后在您写入的所有有效项中保留有效位 1。然后,您可以通过在弹出项目时只写一页将其更改为 0,将其标记为无效。
由于您无法在此方案中重用物品槽,因此您的堆栈将不断增长到内存的尽头。这实际上是您想要的,因为在 NAND 闪存死之前只能写入这么多次,并且这种方案会稍微分散写入。当您到达空间的尽头时,您可以擦除并重写整个内容以消除所有空白。
最终可能会出现一长串无效项目,因此跳过它们可能涉及扫描所有中间项目。您可以通过在每个项目中保留多于一位来解决此问题。当你写一个有效的项目时,你使用这些位来存储它之前的无效项目的数量加上 1。这让你可以快速跳回并在恒定时间内弹出。
然后,当您想将一个项目标记为无效时,您可以将为此计数保留的位更改为全 0,同样只需写入一页即可。此零计数无法出现在有效项目中,因此它用作无效标记。