data-structures - 在页可写扇区可擦除闪存中实现标准堆栈
问题描述
我想在我的微控制器固件中实现一个简单的堆栈。我想实现的堆栈是这样的,即标准的东西。
问题是我使用的闪存 IC 支持写入的页面粒度和擦除的扇区粒度,就像任何其他 NAND 闪存一样,在闪存上写入一些数据之前,您应该擦除该部分。
因此,作为总结,我擦除了一个扇区并在其第一页上写入了一些数据。为了重写该页面的一个字节,我应该先擦除整个扇区。
在我的堆栈中,
| ○ | ○ | ○ | ○ | ○ | ○ |
我推送一些数据:
| W | W | W | ○ | ○ | ○ |
然后弹出其中一个:
| W | W | 磷 | ○ | ○ | ○ |
现在我想推送另一个数据。这里问题出现了。如果像标准堆栈一样,我决定写入以前的数据并更改索引,我必须先删除整个扇区!因此我应该以编程方式解决这个问题。
有任何想法吗?
PS:闪存映射为:16 Blocks -> Each Block = 16 Sectors -> Each Sector = 16 Pages -> Each Page = 256 Bytes
我在页面级别有一个写入命令,其中包含扇区和块的偏移和擦除命令。
解决方案
好吧,如果您不想每次推送都写入整个扇区,那么您将不得不容忍堆栈中的一些旧数据:
| W | W | 磷 | W | ○ | ○ |
您需要在每个项目中至少保留一位,以便区分有效和无效。假设扇区擦除用 1 填充它,然后在您写入的所有有效项目中保留有效位 1。然后,您可以通过在弹出项目时仅写入一页将其更改为 0,将其标记为无效。
由于您不能在此方案中重用项目插槽,因此您的堆栈将不断增长到内存的末尾。这实际上就是你想要的,因为 NAND 闪存在它死前只能被写入这么多次,而且这种方案会在一定程度上分散写入。当您到达空间尽头时,您可以擦除并重写整个内容以消除所有间隙。
您最终可能会得到一串很长的无效项目,因此跳过它们可能涉及扫描所有中间项目。您可以通过在每个项目中保留多个位来解决此问题。当你写一个有效的项目时,你使用这些位来存储它之前的无效项目的数量加 1。这让你可以快速向后跳并以恒定的时间弹出。
然后,当您想将某个项目标记为无效时,您可以将为此计数保留的位更改为全 0,同样只需写入一页。此零计数无法出现在有效项目中,因此它用作无效标记。
推荐阅读
- flutter - 如何在 Flutter 上获取其他应用程序的通知数据,尤其是在 IOS 上?
- google-sheets - 在 googlesheet 中为每个学生生成/制作图形并将图形图像自动保存到 gdrive
- singularity-container - 为什么奇异容器中的命令无法运行?
- r - Aov 模型摘要在函数中使用时不打印
- netsuite - netsuite restlet 错误“消息”:“ReferenceError:\“Ext\”未定义。(app-all.js#1)。”
- python - PyPDF2 在追加时打印数百个空白页
- flutter - 如何导航到 Flutter Flame Engine 游戏小部件之外的小部件
- python-3.x - ConnectionRefusedError: [Errno 111] Connect call failed -- 我需要定位哪些 IP?
- linux - 如何在linux上将安装的gdb添加到系统路径
- python - 将 tradingview 的 pine 脚本转换为 python