探索Dhara:为小型MCU打造的NAND闪存转换层
Dhara是一款专为资源受限的系统设计的小型闪存转换层,它旨在管理和优化NAND闪存。项目的核心是提供了一个可变的块接口,支持标准的读取和写入操作,并且有以下额外亮点:
- 完美的磨损均衡:任何两个物理区块的擦除次数之差不会超过1。
- 修剪功能:逻辑扇区可以被删除以提升性能,当其内容不再需要时。
- 数据完整性保障:逻辑扇区的写入(和修剪)操作是原子性的。即使电源故障,状态也会回滚到最近的同步点。同步点定期发生,但也可以按需触发。
- 实时性能:所有操作,包括启动,都是最坏情况下的O(log n),其中n为芯片大小,假设坏块均匀分布。
Dhara的实现对底层NAND芯片不做过多假设,几乎可以用于任何可用的芯片,并且可以利用硬件的额外特性,例如:
- 不占用OOB(Out-Of-Band)数据。所有的OOB字节都可以用于ECC。
- 可以利用NAND芯片内部缓冲的复制操作。
- 如果可用,可以利用芯片内置的ECC。
- 不需要部分页编程功能。然而,如果芯片支持,它可以通过将真实页面大小除以允许的重新编程操作数来提供更小的伪页面大小。
- 若芯片支持,它可以利用部分读取能力,但必须进行错误检查和校正。
Dhara的实现包含dhara/
子目录中的文件,以及你需要提供的NAND层实现。顶级接口是map.h
中描述的一系列函数(详情参见头文件内的注释)。主要包括:
init
: 初始化一个映射层实例resume
: 扫描映射并恢复保存的状态clear
: 删除所有数据capacity, size
: 获取使用统计信息find
: 获得逻辑扇区的物理位置read
: 读取一个逻辑扇区write
: 写入一个逻辑扇区copy_page
: 将原始闪存页复制到逻辑扇区copy_sector
: 将一个逻辑扇区复制到另一个trim
: 从映射中删除一个逻辑扇区sync
: 确保对映射的更改已提交gc
: 手动触发垃圾回收
为了提供NAND层,你需要实现nand.h
中描述的函数集(查看注释获取详细信息)。概括来说,你需要提供以下操作:
is_bad
: 检查一个区块是否为坏块mark_bad
: 标记一个NAND区块为坏块erase
: 擦除一个NAND区块prog
: 编程一个NAND页,包括ECC和校验和is_free
: 判断一个页面是否为空(未编程)read
: 读取(可能是部分)NAND页面,如有必要尝试ECCcopy
: 利用可能的内部缓存将一页复制到另一页
查阅你的芯片数据手册以获取这些操作的具体信息。大多数情况下,制造商会在OOB区域指定ECC和坏块标记的布局方案。特别注意工厂标记的坏块的标记!
如果你的ECC机制使得编程全0xff页面等同于无操作,那么在is_free()
中只需检查页面内容是否全为0xff即可。
请注意,对于部分读取,你必须读取足够多的页面以便应用ECC并检查不可纠正的错误。必须检测到不可纠正错误才能确保数据完整性保证有效。这可能需要使用校验和加上ECC。如果这样做了,请确保校验和字节也受到ECC保护!
在ecc/
子目录中,你可以找到两种流行的ECC机制(汉明码和BCH码)的实现。每种都实现了对不同大小的块(如256或512字节)的ECC。
总的来说,Dhara是一个强大的工具,适合在资源有限的嵌入式环境中管理NAND闪存,提供了可靠的数据安全性和高效的存储管理。无论是物联网设备、智能家居产品还是工业自动化系统,Dhara都能成为你存储解决方案的理想选择。现在,就加入Dhara的世界,发掘它的无限潜力吧!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考