是否可以在Atmega 328p(内部RAM为2KB)上使用最小扇区擦除大小为4KB的SPI闪存芯片?
我看到的问题:为了将数据写入闪存,必须擦除页面。如果要更新扇区内的数据,则首先需要读取扇区内的所有页面,将其保存在芯片外,擦除扇区,然后按顺序将页面写回更改。
但是4KB的扇区无法保存在2KB RAM中,那么其他人在这种情况下使用什么解决方案?因为我已经看到在此设置中使用了Arduino,但无法确定其解决方案。
(Arduino只是这个问题中小型微控制器的一个示例)
答案 0 :(得分:2)
您可以简单地使用双冗余页面方案。给定这样组织的两个 4kb页面:
Page A Page B
+------------+ +------------+
| Sequence A | | Sequence B |
!~sequence A | !~sequence B |
+------------+ +------------+
| | | |
| | | |
| Data A | | Data B |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
+------------+ +------------+
最初,您编写Data A
并将Sequence A
设置为其反~Sequence A
为零。在启动时,您检查每个页面的序列号,并将具有最高有效序列号的页面(当'sequence ^〜sequnece == 0xff时有效)设置为 Current Read Page ,另一个设置为当前写页面。
更新数据时,擦除当前写入页面,写入 data 区域,然后将序列号设置为读取页面的序列号加1。 (取模256),并设置其倒数。然后交换当前的读/写页面。更新时,您可以将数据从一个页面复制到另一页面,而不用缓冲整个页面,并且仅修改要更改的部分。
如果在写入过程中出现电源故障或复位,则页面序列号将无效,因为它是最后写入的,并且序列和反向序列写入都必须完成,因此部分写入的数据将无效,并且上一个有效页面将在启动时被选择。
选择当前活动页面时,您当然必须处理环绕式操作(即,当序号为255并且为零时,零为更新的值)。
此方案适用于经常读取和很少写入的数据。 NV读/写周期的性质和频率将决定一种合适的机制,因为不同的解决方案适用于顺序记录或非易失性事件计数器。
答案 1 :(得分:0)
还不清楚,您希望编写什么内容(大小)以及执行频率。
您可能会想到几个较小的NV块,它们远小于页面大小。每个NV块都有一些用于标识该块的块头(例如BlockID + Size)。然后,只要新的NV块适合该页面,您就可以更新该页面。如果不是,请将其写入下一页,并将所有最新的其他块也复制到新页面上。然后,您可以擦除旧页面,同时准备下一次交换。