我们在 SDHC 上的一个文件中存储了一个计数器。计数器由 12 个字节组成。计数器值通过以下代码定期更新:
int fd = open( m_path, O_CREAT | O_TRUNC | O_WRONLY, 0 );
write( fd, (char*)m_count, (1 + m_maxId) * sizeof( ULONG ) );
close( fd );
我的问题是:假设 SDHC 支持内部磨损均衡,在这种情况下会应用它吗?或者我是否需要实际删除文件并打开一个新文件才能实现这一点?
我担心由于同一个文件被重复使用,也许相同的物理位置被一遍又一遍地写入。
答案1
我担心由于同一个文件被重复使用,也许相同的物理位置被一遍又一遍地写入。
嗯,这正是磨损均衡的全部意义所在。
到达存储卡后,所有操作都要经过“闪存转换层”,该层会自行决定数据的存储位置;其工作是在逻辑块地址(由操作系统发布)和物理位置(在闪存上)之间进行转换。
这就是磨损均衡发生的地方——FTL 确保即使操作系统请求写入相同的逻辑块,它们也会映射到不同的物理位置。
答案2
补充另一个答案:闪存的工作方式有点不同......它实际上不允许随机写入。
NAND 闪存只允许一位从 1 翻转为 0。要将其翻转为其他方式(从 0 翻转为 1),您需要擦除整个页- NAND 的一部分通常为 4 kiB 或更大(我在微控制器的内部 NAND 中看到过 128 kiB 的页面)。
最简单的做法是将整个页面加载到 RAM 中,更改要更改的位,擦除页面,然后再次写入。除了增加磨损之外,如果在此过程中断电,还存在丢失数据的风险(不太可能,但确实会发生)。
虽然我们不知道(并且可能不会)内部磨损均衡在商业 eMMC 或 SD 存储器中的具体工作原理,但我们可以研究它是如何在软件中实现的,对于使用非托管 NAND 的设备(常见于工业计算机、一些路由器和类似设备)。
一般来说,简化的算法是:
- 将您的文件和一些周围数据(因为您的文件很小)读取到 RAM
- 修改 RAM 中的数据
- 将修改后的数据写入闪存中的空白位置
- 将旧位置标记为脏位置
如果页面中的每个位置都被标记为脏,则可以安全地擦除它。这是在一个单独的进程中完成的,这个进程恰如其分地称为垃圾收集。