大家好!我是大聪明-PLUS!
当我深入参与嵌入式设备开发的硬件测试时,我和设计工程师有时会发现,NAND 或 eMMC 组件的选择非常有限。这需要对每个组件进行额外的耐用性和性能测试。我经常需要测试候选芯片的整体读写性能、交易速度等等。于是,我想,为什么不与其他面临类似挑战的专家分享我的经验呢?在本文中,我想解释一下什么是闪存,它为什么会失效,我是如何组织测试的,以及如何通过测试来最大限度地降低开发中设备存储设备选择的风险。
欢迎对此主题感兴趣的任何人继续阅读。
❯ 免责声明
首先需要澄清的是,本文并非旨在全面介绍闪存,也不会涵盖行业标准,也不会深入探讨固态硬盘 (SSD) 或其他与嵌入式存储无关的主题。我仅提供一些介绍,以便工程师在选择特定存储设备时能够了解其对被测系统的影响、相关流程、评估标准以及如何做出最终选择。当然,我所涵盖的大部分内容都欢迎批评和补充。欢迎任何合理的异议。期待您的评论。
❯ 一点历史
在开始测试任何东西之前,您需要了解什么是闪存、它如何工作、它的弱点是什么,以及可以使用什么标准来评估这种类型的内存的质量和性能。
让我们来探究一下这种存储器最初被称为“闪存”的原因。首先,我们需要回顾一下这种存储器的历史。最初尝试创建基于晶体管的数据存储设备,最终发明了紫外线可擦除只读存储器 (EPROM)。这种存储器很容易通过外壳顶部的透明石英玻璃窗口识别,透过该窗口可以看到硅芯片本身,擦除时紫外线会照射到该窗口。为了防止芯片意外暴露,该窗口被一层特殊的不透明贴纸覆盖。
这些芯片看起来是这样的:
该设备使用专用编程器进行编程。例如,使用这个:
只有使用强紫外线光源(例如汞蒸气光源)才能从 EPROM 中擦除信息。
例如,像这样:
擦除过程让其发明者、东芝工程师有泉翔二(Shoji Ariizumi)想起了简单的闪存盘,而这个名字也牢牢地确立了其作为此类非易失性存储器的稳定名称的地位。但EPROM的发明者、英特尔工程师多夫·弗罗曼(Dov Froman)应该获得荣誉,他早在1971年就为这项数据存储技术申请了专利。
❯数据存储技术
与此同时,一种采用电数据擦除方法的存储器EEPROM被发明,它通过提供更简单的从存储器中擦除数据的程序,带来了当今常见的信息存储方法的出现。
让我们看看数据是如何存储在闪存中的。每种闪存的主要组件都是所谓的 FGMOS 晶体管,即浮栅 MOSFET。与普通 MOSFET 不同,它在控制栅极和 p 层之间有一个额外的栅极(浮栅)。
浮栅的特殊之处在于它完全被电介质层绝缘,并且存储在那里的负电荷可以在其中保留相当长的时间。
改变浮栅中的电荷(即“写入”和“擦除”过程)是通过在控制栅极和源极之间施加特定电压来诱发隧道效应来实现的。为了增强这种效应,还会在晶体管本身的沟道中额外通入电流(即所谓的热载流子注入现象)。当电压移除时,电子会被捕获在介电屏障之间,从而阻止累积的电荷逃逸并在那里停留很长时间。
读取是通过位于基极的场效应晶体管进行的,该晶体管的浮栅用作主栅极,并且相应的读取电路检测电流的流动或不存在。
❯ NOR闪存
“闪存”一词涵盖了多种技术,这些技术能够生产出具有各自独特特征的最终产品。第一个也是最关键的特征是存储单元在晶体管逻辑层面的构造方式。最常见的两种类型是 NOR 和 NAND,它们在某种程度上让人联想到相应的逻辑门。
NOR 和 NAND 技术也有混合版本,例如 DINOR 和 SuperAND。DINOR 由三菱开发,利用多晶硅子位线来降低功耗并提高数据传输速率。SuperAND 架构则简单地将可编程单元闪存单元与内存管理结合在一起,无需纠错机制和内存管理算法。我想您可以通过搜索这些技术的名称来熟悉它们。
NOR 结构的特点是所有单元都并联连接到位线。当逻辑“1”施加到连接到位线的位的控制栅极时,它会转换为逻辑“0”状态,这对应于逻辑 NOR 操作。读取模式下的单元选择通过字线执行。结果是一个经典的行列矩阵,单元位于行列的交叉点处。
NOR 存储器具有几个与 NAND 存储器不同的特性。NOR 存储器允许以极高的速度访问任何存储单元,而无需顺序读取大块数据。NOR 存储器可以访问小至一个字节的数据,这在以小增量更改数据时至关重要。这使得 NOR 存储器更加可靠,但也影响了单位面积的晶体管密度,其密度明显低于 NAND,最终影响了这种存储器的尺寸和成本。因此,NOR 存储器最常用于高度可靠的系统,在这些系统中,稳定性和耐用性至关重要,但存储容量并非关键。
还值得注意的是,NOR 单元的读取访问速度明显高于 NAND,需要几十纳秒,而对于 NAND,此操作需要几十微秒。
❯ NAND 闪存
让我们来看看 NAND 存储器的组织结构。NAND 结构基于串联基本单元的原理,而 NOR 架构则只使用一个单元。这导致 NAND 存储器形成了一个三维阵列,访问方案也十分复杂。正如您所见,访问单个存储单元是不可能的;读取操作需要跨整个单元组进行。
在这个电路中,增加了两个MOSFET,第一个是位线选择晶体管,第二个是地选择晶体管。
现在让我们看看如何使用这种内存组织来组织对每个单元的数据进行读写。
-
一行位对应一行存储单元;
-
如果至少一个晶体管关闭,位线将为高电平,只有当整个晶体管链都打开时,位线才会为低电平;
-
打开晶体管和改变浮栅状态的电压电平有明显的分离;
-
为了读取单个单元,我们不感兴趣的晶体管被打开而不改变浮栅的状态,并且读取所需的单元。
这种存储单元的排列方式显著增加了单位面积存储元素的数量。当然,这种存储组织方式要复杂得多,并且仍然会影响访问存储单元的速度,但由于存储设备发展的主要方向是增加存储数据量,因此 NAND 仍然是更佳的选择。让我们继续更详细地探讨它。
❯ SLC、MLC、TLC、QLC 和 PLC
为了提高 NAND 存储器的存储密度和总容量,人们开发了各种各样的技巧。其中之一就是引入单元内电荷水平的可变性,不仅通过电荷的存在与否来编码 0 和 1,还可以对电荷水平进行排序。
因此,可以创建几种类型的内存,每种类型都有其优点和缺点:
-
SLC(单层单元)。单层单元存储 1 位数据。这是最昂贵、最可靠、最耐用的存储单元技术。每个单元可承受高达 100,000 次写入/擦除循环。
-
伪SLC(伪单层单元)。类似于多层单元(MLC),但工作在SLC模式下。每个单元存储1位数据。伪SLC价格略低,因此可靠性和使用寿命不如SLC。
-
MLC(多层单元)。它是SLC的替代方案,代表多层单元。其独特之处在于MLC单元本身是模拟存储设备,而非数字存储设备。这意味着它存储的是特定的电荷量,而不是比特位。通过在浮栅上注入精确的电荷,可以将两个数据位编程到单个单元中。通过监控电流水平,可以清晰地识别四种状态,分别对应以下两位组合之一:11、10、01、00。它的成本和使用寿命适中,同时对于典型应用而言足够可靠。每个单元可承受多达10,000次写入/擦除循环。
-
TLC(三层单元或 3 位 MLC/MLC-3)。一种三层单元,可存储 3 位信息,并可承载 8 层电荷。它成本低廉,可靠性也与之相似。其使用寿命也相对较短。每个单元最多可承受 3000 次写入/擦除循环。
-
QCL(四层单元或16LC)。一种四层单元,可存储4位信息,即每个单元16层。这是最便宜、最不可靠的单元结构,磨损相对较快。每个单元最多可承受1000次写入/擦除循环。
-
PLC(五级单元)。一种很有前景的五级单元,可存储 5 位信息,据我所知,在撰写本文时,它尚未用于量产产品。
可以得出明显的结论:
-
与 SLC 相比,MLC 内存的重写次数较少;
-
SLC内存速度会更快,意味着基本操作执行速度会更快,整体性能会更高;
-
SLC内存仅使用一个电压阈值,出现问题的可能性要小得多。
了解了这一点,我们可以清楚地得出结论:SLC 内存比 MLC 内存更可靠,整体寿命也更长。然而,SLC 内存的价格会高得多,容量更小,位深度更高——维持精确充电的难度更大,而且更复杂单元的磨损速度更快。
❯ 3D NAND
优化和改进远不止于此。此前,大多数闪存芯片都是在单晶圆上制造的,基于包含存储单元的扁平单层结构。然而,在掌握了20纳米以下晶体管制造工艺后,新的技术问题和挑战随之而来,显著降低了NAND存储器的可靠性。其中一个问题是,在20纳米以下工艺技术下,存储单元非常小,以至于存储信息的电荷开始自由地从一个存储单元流向另一个存储单元。
后来,一种用于物理排列存储元件的新技术被开发出来,这次是垂直排列而不是水平排列。什么是 3D NAND 存储单元?请看下图:
3D NAND 单元呈圆柱形,其外层用作栅极,内层用作绝缘体。外层和内层之间是存储数据位的层。这些单元逐层存储,形成堆叠。
这使得单位面积存储的信息量得以增加,存储可靠性也提高了2到10倍。从那时起,工程师们面临着诸多挑战,包括增加闪存容量、优化其功耗以及开发新的工程解决方案,包括各种类型的内部存储单元布局、单元尺寸的减小等等。我们暂时先不讨论存储技术的开发,因为有大量的资料可以免费获取。我们将转而讨论NAND存储器的内部设计。
❯ NAND结构
现在是时候更详细地研究一下 NAND 存储器的组织结构了。NAND 存储器可以由几个不同的组件组成:
-
单元 (Cell)。闪存的最小元素,用于以位级别存储数据。它无法进行原子读写操作。
-
页面。这是一些可以擦除或读取的单元格数组。
-
块是可以寻址进行数据删除操作的页面数组。它通常包含几兆字节。
-
晶体。单个物理微电路封装在一个微电路外壳中,共享电源和控制信号。看起来就像是几个单独的微电路简单地并联在一起,然后放在一个外壳中。
-
控制器。微电路的一个独立部分,用于管理交互逻辑、实现有针对性的操作,并提供访问外部设备和单元阵列所需的接口。
❯ 读写、擦除块的操作
让我们来看看基本操作。最简单的数据写入或读取发生在页面级别,涉及将位从默认状态(即从 1 到 0)反转。一个重要特性:一个块中的每个页面只能写入一次。要重新编程一个页面,必须擦除整个块。
批量数据删除需要块级操作。但是,无法仅擦除块的一部分。擦除操作比在页面级执行的写入或读取操作慢得多。
当某个块不再能用于存储数据时,它就会被标记为“坏块”。块在被擦除时会磨损,每个闪存都包含一个特殊的块擦除计数器,可以使用特殊实用程序读取。
这里没有什么特别的技巧。我们继续吧。
❯ 主要运营问题
让我们来看看使用闪存时出现的主要问题。主要问题是存储单元的寿命有限,其以写入/擦除次数来衡量。幸运的是,读取过程对整体寿命的影响并不显著,下文将对此进行详细介绍。
存储单元性能下降的另一个原因是无法单独控制每个单元的浮栅电荷。由于写入和擦除操作同时发生在整组单元上,因此写入控制单元会根据参考单元或平均值来控制电荷注入阈值。随着时间的推移,电荷水平会逐渐变得不一致,并超出写入控制单元可以补偿的正常限值。本质上,由于单元的同一性程度发生变化,它们会被淘汰。遗憾的是,随着半导体拓扑结构变得越来越小,制造具有相同特性的相同元件变得越来越困难。
磨损的另一个原因是构成绝缘体和导体的原子逐渐相互扩散,而口袋区域的电场梯度以及写入和擦除过程中绝缘体的周期性电击穿加速了这种扩散。这会导致边界模糊和绝缘水平下降,从而缩短电荷存储时间。
除了纯粹的物理原因外,闪存还具有一些特定的特性和操作规则,这些特性和规则可能会加速存储单元的退化。在最便宜的 NAND 存储器中,经常会出现单个块被不断擦除和写入的情况,从而导致快速磨损。更先进的 NAND 存储器会采用特殊的磨损优化机制、写入监控以及跨物理单元的数据重新分配,以确保磨损均匀。存储器在制造过程中还会内置一定量的备用内存,可在重新分配期间使用。
此外,随着时间的推移,还可能出现一些其他特征:
-
浮栅电荷可能会随着时间的推移而“泄漏”。这被称为软单元间干扰。它可能导致数据完整性问题,包括在写入数据时。这意味着数据存储时间越长,读取时无错误的可能性就越小。这个问题目前是存储单元小型化的一大障碍。
-
用于组织单元的晶体管特性存在差异,在写入相同逻辑电平时,由于电荷量差异,存在读取错误数据的风险。读取操作也是如此。这些情况通常不太可能发生,但如果对 NAND 闪存的有效写入在后续读取过程中开始出现错误,则需要注意。
现在让我们看看使用 NAND 内存时最常发生的错误。
❯ 读取分发错误
由于 NAND 存储器是按块组织的,并使用电荷水平检测来确定哪些位存储在特定单元中,因此从有缺陷的块中读取数据并不像 NOR 那样简单,因为 NOR 中的每个单元都可以单独读取。
此错误是由读取操作引起的。我将更详细地解释此错误发生的机制。读取电压最初高于可能的最大阈值电压,但远低于重新编程或擦除单元所需的电压。由于在读取操作期间参考电压施加到整个页面,因此单个单元在读取操作期间保持非活动状态。读取所需数据后,该电压会被移除,但当操作完成时,它已经影响了附近未读取的单元,阈值电压水平会发生变化,尽管变化很小。
当然,单次读取之后没有任何变化,但几百万次读取之后,情况就发生了变化,错误率也随之稳步上升。这意味着,对于采用 16 nm 工艺技术制造的 MLC NAND 存储器,每读取 10^5 - 10^6 页就会有一个比特失真。因此,随着单元深度的增加,错误率也会随之增加。
解决此问题的主要方法是使用 ECC 算法进行数据校正,或将块移动到其他位置。但是,务必记住,移动操作属于擦除/写入操作,并且单元的寿命也是有限的。
❯ 程序分发错误
这种错误的本质与上面讨论的错误有些相似。唯一的区别在于,写入操作所需的电压明显高于读取操作,并且由于元件之间的寄生电容耦合,相邻的单元也会受到影响。
用于制造 NAND 的工艺技术越小,这种影响就越明显。
解决该问题的主要方法是简单的块传输。
❯ 过度编程错误
这种情况发生在页面重新编程期间,位于同一块中但未参与数据修改操作的相邻单元的阈值电压过高,即偏离了原始指定值。这种情况最常发生在由于某种原因,擦除后保留了过高初始电压的单元上。这种情况最常发生在接近使用寿命的单元上。
解决该问题的主要方法是简单的块传输。
❯ 保留错误
随着时间的推移,单元中的数据容易损坏,通常是由于浮栅电压下降造成的。单元磨损越严重,从浮栅通过绝缘层泄漏的电荷就越多,而绝缘层会随着每次写入/擦除循环而磨损。
单元处于关闭状态的时间延长、温度升高、每个单元的位密度增加(MLC、TLC、QLC)、工艺技术的降低以及绝缘层的减少都会加速这一过程。
解决该问题的主要方法是定期使用驱动器并定期将数据从一个块重写到另一个块。
❯“坏”块
让我们仔细看看原始 NAND 闪存中的“坏”块问题。这些坏块可能存在于新芯片中,数量通常由制造商指定,也可能在运行过程中出现。控制器会将每个坏块标记在一个特殊的“备用区域”中。坏块数据通常可以从闪存中检索。
需要注意的是,在原始 NAND 闪存(即非 eMMC)中,坏块标记信息存储在常规备用区域闪存单元中,当整个存储块被擦除时,这些备用区域也会被擦除。因此,为了在擦除之前保留这些信息,必须单独存储这些信息。
处理坏块的常见方法有以下几种:
-
跳过“坏”块。写入时,系统会分析写入操作以确定要写入哪个块,如果该块被标记为“坏”,则在“坏”块之后的下一个块中执行写入操作。
-
块冗余。在这种情况下,芯片的内存分为三部分:用户块区域、块库以及将坏块映射到好块的表。检测到坏块时,用户块区域中的数据会被传输到块库,并在表中创建相应的条目,指示其已被替换。
-
错误校验和纠正。即使块尚未磨损,位也可能偶尔发生随机翻转,最终损坏存储的数据。错误校验和纠正 (ECC) 算法可用于验证写入数据的正确性。此信息通常保存在备用区域中。
❯ 什么是 eMMC?
现在,让我们来谈谈一种配备内部磨损优化机制的存储设备。这种设备就是 eMMC 内存。eMMC 的缩写代表“嵌入式多媒体存储卡”。为了在嵌入式和便携式系统中使用,设计了一种将控制器和单元阵列集成在单个芯片中的设备。本质上,所有用于数据管理、监控已写入和已擦除块以及对齐和重新分配“坏”块的开销功能都已转移到嵌入式控制器。
每个 eMMC 至少包含三个组件:用于与主机系统交互的接口、闪存阵列和控制器。它通常采用行业标准的 BGA(球栅阵列)封装。此外,根据 eMMC JEDEC 标准,所有芯片都具有多个服务寄存器,可提供大量有关内存状态的有用信息。
使用 eMMC 可以从对齐过程、坏块管理和其他服务操作中提供额外的抽象级别,并允许您安全地使用设计用于与块设备(例如 EXT4)一起使用的文件系统。
❯ eMMC 服务寄存器
eMMC 标准定义了一组服务寄存器,这些寄存器可以从控制器读取,并及时向用户提供有关内存状态的信息。特别值得关注的是 EXT_CSD 寄存器,它提供了大量有用的信息:
-
控制器内置的内存健康报告,其中包括错误块的计数器和块擦除的次数;
-
A 类设备寿命评级以 10% 的增量计算健康状况,通常适用于 SLC 内存;
-
设备寿命评估类型B,以10%的增量计算健康状态,通常指MLC内存;
-
EOL 前信息显示已投入使用以替换发生故障的设备的活跃备用设备的百分比。
❯ 闪存性能和资源
整体健康评级由标记为“坏”并已停用的闪存容量百分比决定。因此,要评估闪存的整体寿命,可以将其计算为擦除的总次数或设备上可写入和擦除的数据总量。
以下是一些可用于进行适当估算的公式。要估算擦除周期数:
E — 擦除周期总数;
B — 区块数量;
L是区块的平均寿命,以擦除次数表示;
E是可以写入Flash存储器的数据总量;
S — 块大小(以字节为单位);
B — 区块数量;
L是区块的平均寿命,以擦除次数表示;
在这种情况下,擦除周期总数更准确,因为块的最终磨损发生在擦除之后,而不是写入一定量数据之后。还值得注意的是温度对存储器寿命的影响。
❯ 在 Linux 中监控 eMMC 内存的状态
由于本文面向使用基于嵌入式 Linux 的嵌入式系统的开发人员和测试人员,因此我们将考虑用于监控 Linux 中闪存性能指标的主要工具。
关于 eMMC 健康状况的首要信息来源是来自控制器服务寄存器的信息。获取此信息最合适的工具是制造商提供的实用程序或开源 mmc-utils 套件。这些实用程序通常实现大多数协议功能,包括从服务寄存器(例如 EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A、EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B 和 EXT_CSD_PRE_EOL_INFO)读取数据。
利用这些寄存器中的信息,我们可以确定设备的使用寿命,正如 JEDEC eMMC 标准所定义的那样。首先,让我们看一下用于实现该接口的协议版本:
root@zynq-7000:/bin# mmc extcsd read/dev/mmcblk1
=============================================
Extended CSD rev 1.7(MMC 5.0)
=============================================
这些信息表明,我们正在处理符合 JEDEC 5.0 标准的 eMMC。然后,我们可以过滤输出并获取性能信息:
root@zynq-7000:/bin# mmc extcsd read/dev/mmcblk1 | grep LIFE
Device lifetime estimation type B [DEVICE_LIFE_TIME_EST_TYP_B: 0x01]
Device lifetime estimation type A [DEVICE_LIFE_TIME_EST_TYP_A: 0x01]
eMMC Life Time Estimation B [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]: 0x01
eMMC Life Time Estimation A [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x01
root@zynq-7000:/bin# mmc extcsd read/dev/mmcblk1 | grep EOL
Pre EOL information [PRE_EOL_INFO: 0x01]
eMMC Pre EOL information [EXT_CSD_PRE_EOL_INFO]: 0x01
每个 eMMC 型号的数据表都包含一个用于解释这些寄存器中值的表。
因此,我们可以说这张闪存卡是新的,并且根据所有指标处于正常状态。
请注意,使用标准实用程序时可能不会显示一些有用的信息,例如坏块计数器或已擦除块的数量,而使用 eMMC 供应商提供的实用程序读取 EXT_CSD 寄存器时则可用。
有时,eMMC 驱动程序提供从 sysfs 树读取内存健康信息的功能:
root@zynq-7000:/bin# cat /sys/class/mmc_host/mmc0/mmc0\:0001/pre_eol_info
root@zynq-7000:/bin# cat /sys/class/mmc_host/mmc0/mmc0\:0001/life_time
❯ I/O 监控
要预测可能的故障日期,了解哪些应用程序写入了过多的数据非常重要。当然,在嵌入式系统中使用闪存的最佳方法是将系统分区挂载为只读模式,并使用使用 RAM 运行的 RAM-FS 磁盘执行所有文件和数据操作。
让我们回到估算闪存潜在故障时间的问题,并大致了解 Linux 中 I/O 堆栈的组织方式。进程可以访问内核来执行文件操作。这些操作的执行方式因所使用的库和编程语言而异,但在某些时候,会发生从用户空间到内核空间的转换。此时,库函数会执行内核系统调用。然后,Linux 内核通过 I/O 堆栈处理此调用,并通过底层驱动程序(可能是块设备驱动程序或 MTD 驱动程序,具体取决于闪存类型(原始 NAND、eMMC 等))将数据发送到存储设备。
以这种方式查看 I/O 堆栈,人们可能会认为可以从用户空间监控一段时间内的 Flash 写入活动,但实际上获得的数据不会非常准确。
由于Linux内核有自己的I/O调度程序,它管理I/O请求队列,并尝试使用其算法最大化I/O性能,实现各种级别的缓存、缓冲区等,因此很明显,操作系统中的任何数据操作都不一定会导致对闪存的操作。
对于监控用户空间的 I/O 操作,我发现 iotop 和 blktrace/blkparse 是最好的。当然,还有其他实用程序和工具可用于 I/O 跟踪,但我们将重点介绍 iotop、blkparse 和 blktrace。
首先,让我们创建一个要写入闪存的文件:
root@zynq-7000:/bin# dd if=/dev/urandom bs=4k count=100000 | pv -L 25k> testfile
为了分析记录过程、记录计数器和负责记录的进程,我们使用 iotop 实用程序:
root@zynq-7000:/bin# iotop --only --batch --accumulated --kilobytes --time–quiet
为了分析每个操作,我们将转向 blktrace 操作跟踪器并使用 blktrace 对其进行过滤:
root@zynq-7000:/bin# blktrace -o - /dev/mmcblk1 | blkparse -i -
此外,blktrace 和 blkparse 实现了大量过滤器,方便对结果数据进行分析和操作。更多信息,请参阅手册和教程。
❯ 闪存寿命评估(eMMC)
评估整体内存资源的另一种方法是选择多个设备(数量越多,图像越具有代表性),执行将数据写入闪存的漫长过程,并通过服务寄存器监控内存状态。参与此测试的设备越多,特定闪存型号的平均数据就越准确。
为了进行此测试,建议准备:
-
侧载版本的 Linux 可启动至 RAMFS 并完全从 RAM 运行;
-
Stressdisk 实用程序 https://github.com/ncw/stressdisk 。它允许您通过将文件写入 eMMC 来循环生成文件。可以生成各种大小的文件。写入后,程序会检查文件并提供读/写速度统计信息。
-
iostat 实用程序将显示有关读/写操作的统计信息。
-
mmc-utils 中的 mmc 实用程序用于读取 EXT_CSD 服务寄存器,我们将根据该信息判断 eMMC 当前的“健康”程度。
在开始任何测试之前,请记住以下几点。由于每个 eMMC 都有自己的控制器,该控制器决定了如何执行损耗均衡,因此无需将数据写入整个 eMMC 内存(即从地址空间的开头到结尾)。循环写入和擦除数据就足够了。如果损耗均衡功能无法正常工作,问题很快就会显现出来。
第二个要点是,控制器对预留块的评估只能基于已擦除/已写入块的计数器,而服务寄存器可能会显示 eMMC 的“健康状况”已耗尽,但实际上,在实际发生写入/读取错误之前,仍有数十 TB 的剩余空间。因此,有必要在闪存实际发生故障之前进行测试。
该测试的总体思路是启动向闪存写入/擦除数据的过程,并在每次测试迭代结束时从 eMCC 服务寄存器输出统计信息。我将提供该测试的总体概念和算法;您可以自己创建一个脚本来自动化测试:
-
将 Sideload Linux 下载到被测设备;
-
将所有必要的实用程序下载到设备;
-
检查所有实用程序是否正常运行:
-
iostat -m — 显示块设备使用情况的统计信息;
-
df -m — 显示有关 Flash 设备上已用可用空间的统计信息;
-
mmc extcsd read /dev/mmcblk0 — 显示 EXT_CSD 寄存器的内容;
-
-
我们检查所需的块设备是否已安装;
-
我们检查当前的健康报告计数器是否等于“健康”闪存的值;
-
在后台运行 stressdisk 实用程序:-s 1000 cycle /mnt/mmcblk0 &
-
我们开始显示统计数据以收集日志:watch -n10 'iostat -m --pretty --human; echo EOL registers:; mmc extcsd read /dev/mmcblk0 | grep -A2 EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A; echo; df -m /mnt/mmcblk0';
-
我们会随着 eMMC 的磨损而监控寄存器值。随着磨损的加剧,计数器会递增。平均而言,这种情况会在数个单位或数十 TB 的连续块写入/擦除之后发生(但也取决于 eMMC 的容量)。
运行测试并查看闪存卡上的写入错误后,您将获得一个日志,其中显示执行的迭代次数以及导致计数器增量的 TWB(总写入字节)值。
❯ 估算闪存(原始 NAND)的寿命
测试原始 NAND 内存的原理与测试 eMMC 内存没有太大区别,只是您必须自己处理坏块计数。在这种情况下,与坏块管理相关的大多数功能都委托给了 Linux 内核内置的 MTD 驱动程序。
有两个工具适合测试 NAND 驱动器的寿命。我将分别介绍它们。第一个是 nandwrite。其测试算法如下:
-
将 Sideload Linux 下载到被测设备;
-
将所有必要的实用程序下载到设备;
-
我们运行一个执行写入和擦除操作的脚本:
#!/bin/sh
i=1
while [ $i > 0 ]
do
echo "########################################"
echo " "
echo "Iteration: $i: "
echo " "
echo "########################################"
echo "Uptime start dd command: "; cat /proc/uptime;
dd if=/dev/urandom | nandwrite /dev/mtd2
cat /sys/class/mtd/mtd*/bad_blocks
sleep 3
i=$(( $i + 1 ))
echo "########################################"
done
-
如果需要在出现第一个坏块后停止测试,可以使用另一个脚本:
#!/bin/sh
i=1
while [ $i > 0 ]
do
echo "########################################"
echo " "
echo "Iteration: $i: "
echo " "
echo "########################################"
echo "Uptime start dd command: "; cat /proc/uptime;
sleep 1
dd if=/dev/urandom | nandwrite -m /dev/mtd2
cat /sys/class/mtd/mtd*/bad_blocks
sleep 1
i=$(( $i + 1 ))
echo "########################################"
done
-
接下来,在出现第一个或新的坏块后,记录迭代次数和写入的数据量。
-
我们重新开始测试并观察出现下一个坏块之前的迭代次数。
-
我们重复步骤6,并计算出现新的坏块之前的平均数据量。
-
我们计算迭代次数,经过该次数后坏块的临界值(来自数据表)将被超过,并且 NAND 被视为不可用。
-
让我们总结一下:第一次迭代期间写入的数据量 + (第二次迭代期间的数据量 * 坏块数量,在此之后 NAND 被视为无法操作)= 总 NAND 资源
-
我们对这些数据量是否足够做出判断。
还有第二个适合测试原始 NAND 的工具——nandtest。其测试算法与 nandwrite 类似,如下所示:
-
将 Sideload Linux 下载到被测设备;
-
将所有必要的实用程序下载到设备;
-
以所需模式运行 nandtest 实用程序:
nandtest --passes 100 --reads 2 /dev/mtd2 2>&1 | tee /tmp/nand_test.log
nandtest --passes 1000000 --reads 1 --offset 0 --length 0x80000 /dev/mtd2 2>&1 | tee /tmp/nand_test.log
-
我们分析 nand_test.log 文件以查找错误。
通过这个简单的方法,你可以粗略地估计出所选内存芯片的使用寿命。
❯ 结论
最后,我想说的是,这些信息只是了解闪存是什么、它如何工作以及如何组织评估测试的一个小介绍片段,在这种情况下,许多以前可用的产品必须用中国或其他类似产品替换,其质量是不可预测的,以及如何避免所选内存快速失效且不符合预期的情况。
基于本文所获得的知识、测试结果以及由此收集的信息,我们可以得出许多关于闪存性能的结论:其速度、实际寿命、失效速度、导致失效的原因、用于优化单元阵列寿命的算法质量等等。如果您对以上内容有任何补充,请留言并分享您的闪存测试方法,无论是 NAND 还是 eMMC。
感谢您的关注。