ARM 处理器平台 eMMC Flash 存储磨损测试示例

news2025/3/3 4:47:37

By Toradex秦海

1). 简介

目前工业嵌入式 ARM 平台最常用的存储器件就是 eMMC Nand Flash 存储,而由于工业设备一般生命周期都比较长,eMMC 存储器件的磨损寿命对于整个设备来说至关重要,因此本文就基于 NXP i.MX8M Mini ARM 处理器平台演示 eMMC 器件磨损测试的示例流程。

关于 eMMC 存储器件的基本介绍可以参考如下文章,eMMC 存储器件通常包含有 eMMC Nand Flash 控制器和一定数量的 Nand Flash 存储颗粒来组成,ARM 处理器主机对于 eMMC 的操作都要通过 Nand Flash 控制器进行映射,同时 Nand Falsh 控制器还负责 Wear leveling/ECC/Bad Block Management 等功能以保证 eMMC 器件稳定可靠工作。

eMMC (Linux) | Toradex Developer Center

eMMC 存储器件的磨损寿命主要由其包含的 Nand Flash 颗粒存储单元的 P/E(programming and erasing) 次数来决定,不同 Nand Flash 颗粒种类通常的 P/E 次数不同,一个大概的参考如下,不同品牌不同工艺的颗粒会有差异。

./ SLC Nand Flash - 10K - 100K P/E Cycles

./ MLC Nand Flash - 3K - 10K, normally 3K P/E Cycles

./ 2D TLC Nand Flash - normally 1K P/E Cycles

./ 3D TLC Nand Flash - normally 3K P/E Cycles

但是由于 Nand 控制器操作 Nand Flash 存储单元 programming 写入最小单位是 Page,而 erasing 擦除最小单位是 Block,因此当写入/擦除数据不是对应最小单元整数倍时候就会产生额外的开销,同时还附加其他 Wear leveling/Garbage collection/Bad Block Management 等功能产生的开销,就会导致实际写入的全寿命数据量要小于理论上按照单元 P/E Cycles 计算的数据量(eMMC capacity * P/E cycles),这个差异就是 WAF (Write Amplification Factor)写放大因子((eMMC capacity * P/E cycles)/actual full-lifetime data written)。更多相关说明请参考如下文章。

使用 eMMC 闪存设备的磨损估计

因此由于上述 Nand Flash 控制器地址映射和 WAF 的存在,磨损测试是无法直接将 Host 写入数据和实际 Nand Flash 颗粒的 P/E 对应的,而 WAF 在不同写入情况下又是一个动态数值,所以我们依赖 Linux Kernel mmc-utils 工具或者 eMMC 提供商的专用软件来读取 Extended CSD rev 1.7 (MMC 5.0) 包含的 Health Status 信息,并通过其每 10% 的线性变化和实际写入数据是否对应线性变化,以及最终写入数据量,可以推算出实际的 WAF。

eMMC (Linux) | Toradex Developer Center

关于 CSD Register 中 Health Status 和 Spare Block Register 的定义说明如下

./ Device life time estimation type A/B: life time estimation based on blocks P/E cycles, provided in steps of 10%, e.g.:

0x02 means 10%-20% device life time used.

./ Pre EOL information: overall status for reserved blocks. Possible values are:

0x00 - Not defined.

0x01 - Normal: consumed less than 80% of the reserved blocks.

0x02 - Warning: consumed 80% of the reserved blocks.

0x03 - Urgent: consumed 90% of the reserved blocks.

本文所示例的平台来自于 Toradex Verdin i.MX8MM 嵌入式平台。

2. 准备

a). Verdin i.MX8MM ARM核心版配合Dahlia 载板并连接调试串口用于后续测试

b).参考这里下载 Toradex Yocto Linux BSP6 Reference Image

c).参考这里的说明将上述下载的 BSP Image 安装到 Verdin i.MX8MM 核心板。

d).准备一个 SD 卡,参考这里的说明使用上述下载的 BSP Image 制作启动 SD 卡。

3). 测试流程

a). 将 SD 插入 Dahlia 载板后启动,系统自动会优先从外部 SD 卡 (mmc1) 启动,可以通过如下调试串口 log 信息来进一步判定。

-------------------------------

......

Hit any key to stop autoboot:  0

switch to partitions #0, OK

mmc1 is current device

Scanning mmc 1:1...

Found U-Boot script /boot.scr

......

-------------------------------

b). 因为系统会自动 mount eMMC 对应设备分区,为了后续测试,需要先关闭自动挂载。

-------------------------------

root@verdin-imx8mm-07276322:~# mount |grep /dev/mmcblk0

/dev/mmcblk0p2 on /media/RFS-mmcblk0p2 type ext4 (rw,relatime)

/dev/mmcblk0p1 on /media/BOOT-mmcblk0p1 type vfat (rw,relatime,gid=6,fmask=0007,dmask=0007,allo)

-------------------------------

在设备 Linux 下执行下面脚本关闭自动挂载,执行成功后上述挂载信息就没有了。

-------------------------------

#!/bin/sh -e

systemd-umount /dev/mmcblk0p1

systemd-umount /dev/mmcblk0p2

systemctl stop systemd-udevd

systemctl stop systemd-remount-fs

count=`ls -1 /etc/udev/rules.d/*automount.rules 2>/dev/null |wc -l`

if [ $count != 0 ]

then

rm /etc/udev/rules.d/*automount.rules

fi

-------------------------------

c). 接下来要通过 Linux 磁盘操作工具来进行大量写入数据来测试 eMMC 的磨损, 本文测试使用 fio 工具,当然还有像 dd/hdparm 等工具也可以根据情况酌情选择。

./ 首先创建 fio 配置文件,类似如下,具体说明可以参考 fio 官方文档。

-------------------------------

[global]

bs=32k

direct=0

ioengine=libaio

iodepth=4

verify=crc32c

filename=/dev/mmcblk0 ; emmc device filename

verify_dump=1

verify_fatal=1

randrepeat=0

[write-once]

description=Write once area, used for testing date retention

stonewall

rw=write

verify_pattern=0xaa555aa5 ; fixed data pattern

size=256M

offset=0

[verify-write-once]

description=Verify write once area, used for testing data retention

stonewall

rw=read

verify_only

size=256M

offset=0

[write]

description=Write r/w stress data area with random data

stonewall

rw=write

do_verify=0

offset=256M

[verify]

description=Verify r/w stress data area

stonewall

rw=read

verify_only

offset=256M

-------------------------------

//其中需要说明的是 bs (block size) 的设置需要根据不同的 eMMC 手册中定义的 Optimal Write Size 以尽可能减小 WAF,比如当前测试 eMMC 手册中定义如下

ARM 处理器平台 eMMC Flash 存储磨损测试示例5304.png

实际读取的寄存器数值如下,对应为 32KB,因此 fio 配置文件中 bs 参数设置为 32k 或者其整数倍数,可以保证 Nand Flash 颗粒存储单元写入都是按照 Page Size。

-------------------------------

$ mmc extcsd read /dev/mmcblk0  | grep write

Optimal write size [OPTIMAL_WRITE_SIZE: 0x08]

-------------------------------

./ 然后可以通过类似如下测试脚本来进行一次写入和验证,测试 fio 的配置正确和可用以及当前的 eMMC Health Status 状态

-------------------------------

#!/bin/bash -e

EMMC_DEVICE=/dev/mmcblk0

FIO_TEST_NAME=emmc-pe-test.fio

echo ">> eMMC P/E test preparation on ${EMMC_DEVICE}"

echo ">> eMMC EXTCSD Health Status"

mmc extcsd read "${EMMC_DEVICE}" | fgrep -A1 DEVICE_LIFE_TIME_EST

mmc extcsd read "${EMMC_DEVICE}" | fgrep -A1 PRE_EOL_INFO

echo ">> Write once data"

fio --section=write-once "${FIO_TEST_NAME}"

echo ">> Verify write once data"

fio --section=verify-write-once "${FIO_TEST_NAME}"

-------------------------------

./ 最后可以通过如下循环写入脚本持续写入测试来测试 eMMC 磨损情况。

-------------------------------

#!/bin/bash -e

EMMC_DEVICE=/dev/mmcblk0

COUNT=0

FIO_TEST_NAME=emmc-pe-test.fio

echo ">> Starting eMMC P/E test on ${EMMC_DEVICE}"

while true

do

        echo ">> Run $COUNT"

        echo ">> eMMC EXTCSD Health Status"

        mmc extcsd read "${EMMC_DEVICE}" | fgrep -A1 DEVICE_LIFE_TIME_EST

        mmc extcsd read "${EMMC_DEVICE}" | fgrep -A1 PRE_EOL_INFO

        echo ">> Check write once data"

        fio --section=verify-write-once "${FIO_TEST_NAME}"

        echo ">> Wear eMMC"

        fio --section=write --section=verify "${FIO_TEST_NAME}"

        COUNT=$(($COUNT + 1))

done

-------------------------------

./ 磨损测试一次全盘写入和验证的 log 信息如下,由于实际测试完成时间会非常长,通常根据 eMMC 容量不同可能需要几天甚至十几天时间,本文就不演示最终完成的数据。最后可以根据寿命达到90%以上时候全部 log 信息统计出类似如下表格 eMMC 每磨损 10% 实际 P/E 的次数和数据量,得出 eMMC 的全寿命磨损数据/磨损是否线性以及实际 WAF 数值。另外,关于 LIFE_TIME_EST_A 还是 LIFE_TIME_EST_B 没有标准定义,由各个厂商自行定义,所以实际以厂商定义为准。

-------------------------------

>> Starting eMMC P/E test on /dev/mmcblk0

>> Run 0

>> eMMC EXTCSD Health Status

Device life time estimation type B [DEVICE_LIFE_TIME_EST_TYP_B: 0x01]

 i.e. 0% - 10% device life time used

Device life time estimation type A [DEVICE_LIFE_TIME_EST_TYP_A: 0x01]

 i.e. 0% - 10% device life time used

Pre EOL information [PRE_EOL_INFO: 0x01]

 i.e. Normal

>> Check write once data

verify-write-once: (g=0): rw=read, bs=(R) 32.0KiB-32.0KiB, (W) 32.0KiB-32.0KiB, (T) 32.0KiB-32.4

fio-3.30

Starting 1 process

Jobs: 1 (f=1)

verify-write-once: (groupid=0, jobs=1): err= 0: pid=583: Fri Apr 29 20:04:38 2022

  Description  : [Verify write once area, used for testing data retention]

  read: IOPS=4908, BW=153MiB/s (161MB/s)(256MiB/1669msec)

...

Run status group 0 (all jobs):

   READ: bw=153MiB/s (161MB/s), 153MiB/s-153MiB/s (161MB/s-161MB/s), io=256MiB (268MB), run=166c

Disk stats (read/write):

  mmcblk0: ios=1009/0, merge=0/0, ticks=2390/0, in_queue=2391, util=94.47%

>> Wear eMMC

write: (g=0): rw=write, bs=(R) 32.0KiB-32.0KiB, (W) 32.0KiB-32.0KiB, (T) 32.0KiB-32.0KiB, ioeng4

verify: (g=1): rw=read, bs=(R) 32.0KiB-32.0KiB, (W) 32.0KiB-32.0KiB, (T) 32.0KiB-32.0KiB, ioeng4

fio-3.30

Starting 2 processes

Jobs: 1 (f=1): [_(1),V(1)][100.0%][eta 00m:00s]                                   

write: (groupid=0, jobs=1): err= 0: pid=590: Fri Apr 29 20:17:15 2022

  Description  : [Write r/w stress data area with random data]

  write: IOPS=732, BW=22.9MiB/s (24.0MB/s)(14.4GiB/642435msec); 0 zone resets

...

verify: (groupid=1, jobs=1): err= 0: pid=607: Fri Apr 29 20:17:15 2022

  Description  : [Verify r/w stress data area]

  read: IOPS=4812, BW=150MiB/s (158MB/s)(14.4GiB/97725msec)

...

Run status group 0 (all jobs):

  WRITE: bw=22.9MiB/s (24.0MB/s), 22.9MiB/s-22.9MiB/s (24.0MB/s-24.0MB/s), io=14.4GiB (15.4GB),c

Run status group 1 (all jobs):

   READ: bw=150MiB/s (158MB/s), 150MiB/s-150MiB/s (158MB/s-158MB/s), io=14.4GiB (15.4GB), run=9c

Disk stats (read/write):

  mmcblk0: ios=58819/29449, merge=0/3732727, ticks=143387/81519893, in_queue=81663280, util=99.%

...

-------------------------------

ARM 处理器平台 eMMC Flash 存储磨损测试示例9211.png

4). 总结

本文基于 NXP i.MX8MM ARM 处理器平台说明和演示了 eMMC 寿命磨损测试的流程,同时由于测试是线性写入,得出的结果和实际应用具体情况可能有不同,不过在实际应用中,为了最大程度的增加 eMMC 存储器件的寿命和可靠性,在写入数据时候最好不要无论大小数据每次都直接写入磁盘,最好使用缓存将要写入的数据累积到一定量之后,根据具体 eMMC Optimal Write Size 来最终写入磁盘,以尽可能减少 WAF,提高磨损寿命。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2308750.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

本地部署DeepSeek-R1(Dify发件邮箱、找回密码、空间名称修改)

Dify配置发件邮箱 DIfy默认邮箱配置为空,在邀请团队成员注册时是不会发送邀请链接的,只能通过手动复制生成的注册链接发送给对应的人去注册设置密码。 这样很麻烦,并且在找回密码时也接收不了邮件,无法重置密码。 找到本地部署…

EasyRTC:支持任意平台设备的嵌入式WebRTC实时音视频通信SDK解决方案

随着互联网技术的飞速发展,实时音视频通信已成为各行各业数字化转型的核心需求之一。无论是远程办公、在线教育、智慧医疗,还是智能安防、直播互动,用户对低延迟、高可靠、跨平台的音视频通信需求日益增长。 一、WebRTC与WebP2P:实…

数据库数据恢复—SQL Server附加数据库报错“错误 823”怎么办?

SQL Server数据库附加数据库过程中比较常见的报错是“错误 823”,附加数据库失败。 如果数据库有备份则只需还原备份即可。但是如果没有备份,备份时间太久,或者其他原因导致备份不可用,那么就需要通过专业手段对数据库进行数据恢复…

HTMLS基本结构及标签

HTML5是目前制作网页的核心技术&#xff0c;有叫超文本标记语言。 基本结构 声明部分位于文档的最前面&#xff0c;用于向浏览器说明当前文档使用HTML标准规范。 根部标签位于声明部分后&#xff0c;用于告知浏览器这是一个HTML文档。< html>表示文档开始&#xff0c;&l…

IDEA集成DeepSeek,通过离线安装解决无法安装Proxy AI插件问题

文章目录 引言一、安装Proxy AI1.1 在线安装Proxy AI1.2 离线安装Proxy AI 二、Proxy AI中配置DeepSeek2.1 配置本地部署的DeepSeek&#xff08;Ollama方式&#xff09;2.2 通过第三方服务商提供的API进行配置 三、效果测试 引言 许多开发者尝试通过安装Proxy AI等插件将AI能力…

phpstudy安装教程dvwa靶场搭建教程

GitHub - digininja/DVWA: Damn Vulnerable Web Application (DVWA) Dvwa下载地址 Windows版phpstudy下载 - 小皮面板(phpstudy) 小皮下载地址 1选择windows 版本&#xff0c;点击立即下载 下载完成&#xff0c;进行解压&#xff0c;注意不要有中文路径 点击.exe文件进行安装…

【linux】详谈 环境变量

目录 一、基本概念 二、常见的环境变量 取消环境变量 三、获取环境变量 通过代码获取环境变量 环境变量的特性 1. getenv函数:获取指定的环境变量 2. environ获取环境变量 四、本地变量 五、定义环境变量的方法 临时定义&#xff08;仅对当前会话有效&#xff09; 永…

【Linux高级IO】多路转接(poll epoll)

目录 1. poll 2. epoll 2.1 epoll_ctl 2.2 epoll_wait 2.3 epoll原理 2.4 epoll的工作模式 2.5 epoll的惊群效应 使用建议 总结 1. poll poll也是实现 I/O 多路复用的系统调用&#xff0c;可以解决select等待fd上限的问题&#xff0c;将输入输出参数分离&#xff0c;不需要…

供应链管理系统--升鲜宝门店收银系统功能解析,登录、主界面、会员 UI 设计图(一)

供应链管理系统--升鲜宝门店收银系统功能解析&#xff0c;登录、主界面 会员 UI 设计图&#xff08;一&#xff09;

【Linux系统编程】基础IO--磁盘文件

目录 前言 磁盘的机械构成 盘片介绍 盘片与磁头 数据的存储&#xff08;硬件&#xff09; 磁盘的物理存储 逻辑结构&#xff1a;磁道/柱面、扇面、扇区 磁盘I/O的基本单位与扇区的存储密度 CHS定位法&#xff1a;数据的查找 磁盘的逻辑存储 扇区的抽象结构(数据…

C# .NET Core HttpClient 和 HttpWebRequest 使用

HttpWebRequest 这是.NET创建者最初开发用于使用HTTP请求的标准类。HttpWebRequest是老版本.net下常用的&#xff0c;较为底层且复杂&#xff0c;访问速度及并发也不甚理想&#xff0c;但是使用HttpWebRequest可以让开发者控制请求/响应流程的各个方面&#xff0c;如 timeouts,…

[3/11]C#性能优化-实现 IDisposable 接口-每个细节都有示例代码

[3]C#性能优化-实现 IDisposable 接口-每个细节都有示例代码 前言 在C#开发中&#xff0c;性能优化是提升系统响应速度和资源利用率的关键环节。 当然&#xff0c;同样是所有程序的关键环节。 通过遵循下述建议&#xff0c;可以有效地减少不必要的对象创建&#xff0c;从而减…

1.C语言初识

C语言初识 C语言初识基础知识hello world数据类型变量、常量变量命名变量分类变量的使用变量的作用域 常量字符字符串转义字符 选择语句循环语句 函数&#xff1b;数组函数数组数组下标 操作符操作符算术操作符移位操作符、位操作符赋值操作符单目操作符关系操作符逻辑操作符条…

软件测试中的BUG

文章目录 软件测试的生命周期BugBug 的概念描述 Bug 的要素案例Bug 级别Bug 的生命周期与开发产生争执怎么办&#xff1f;【高频面试题】先检查自身&#xff0c;Bug 是否描述的不清楚站在用户角度考虑并抛出问题Bug 的定级要有理有据提⾼自身技术和业务水平&#xff0c;做到不仅…

TinyEngine v2.2版本发布:支持页面嵌套路由,提升多层级路由管理能力开发分支调整

2025年春节假期已过&#xff0c;大家都带着慢慢的活力回到了工作岗位。为了让大家在新的一年继续感受到 Tiny Engine 的成长与变化&#xff0c;我们很高兴地宣布&#xff1a;TinyEngine v2.2版本正式发布&#xff01;本次更新带来了重要的功能增强------页面支持嵌套路由&#…

Web自动化之Selenium添加网站Cookies实现免登录

在使用Selenium进行Web自动化时&#xff0c;添加网站Cookies是实现免登录的一种高效方法。通过模拟浏览器行为&#xff0c;我们可以将已登录状态的Cookies存储起来&#xff0c;并在下次自动化测试或爬虫任务中直接加载这些Cookies&#xff0c;从而跳过登录步骤。 Cookies简介 …

Storm实时流式计算系统(全解)——中

storm编程的基本概念-topo-spout-bolt 例如下&#xff1a; storm 编程接口-spout的结构及组件实现 storm编程案例-spout组件-实现 这是我的第一个组件&#xff08;spout组件继承BaseRichSput&#xff09;所有重写内部的三个方法&#xff0c;用于接收数据&#xff08;这里数据是…

让deepseek更专业的提示词教程

一、明确需求和目标 在使用DeepSeek之前&#xff0c;首先要明确你的需求和目标。例如&#xff0c;你是要生成一篇学术论文的摘要&#xff0c;还是一个商业文案的大纲&#xff0c;亦或是一段技术分析。明确的目标可以帮助你更有针对性地编写提示词。 二、使用专业术语和结构化…

《Python实战进阶》No 9:使用 Celery 实现异步任务队列

第9集&#xff1a;使用 Celery 实现异步任务队列 引言 在现代 Web 应用中&#xff0c;许多操作&#xff08;如发送邮件、处理文件上传、执行复杂计算等&#xff09;可能需要耗费较长时间。如果这些操作直接在主线程中执行&#xff0c;会导致用户请求阻塞&#xff0c;降低用户体…

【Mark】记录用宝塔+Nginx+worldpress+域名遇到的跨域,301,127.0.0.1,CSS加载失败问题

背景 想要用宝塔搭建worldpress&#xff0c;然后用域名直接转https&#xff0c;隐藏掉ipport。 结果被折磨了1天&#xff0c;一直在死活在301&#xff0c;127.0.0.1打转 还有css加载不了的情况 因为worldpress很多是301重定向的&#xff0c;所以改到最后我都不知道改了什么&am…