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

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.mzph.cn/web/70749.shtml

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

相关文章

Comfy UI 快捷键

Comfy UI 页面的快捷键操作(记录下,以防忘记): 捷径命令Ctrl Enter将当前图表排队等待生成Ctrl Shift Enter将当前图表排成第一个生成图表Ctrl Z/Ctrl Y撤消/重做Ctrl S保存工作流程Ctrl O加载工作流Ctrl A选择所有节点A…

uniapp 本地数据库多端适配实例(根据运行环境自动选择适配器)

项目有个需求,需要生成app和小程序,app支持离线数据库,如果当前没有网络提醒用户开启离线模式,所以就随便搞了下,具体的思路就是: 一个接口和多个实现类(类似后端的模板设计模式)&am…

HIVE SQL函数之比较函数

背景:今天接到一个临时需求,需要比较abc的大小,但是abc三个字段都存在为空的情况。 开发:对于这个开发很简单,因为比较函数有太多了,首先想到的是用case when去进行一个非空的判断,再去比较用I…

AI探索笔记:浅谈人工智能算法分类

人工智能算法分类 这是一张经典的图片,基本概况了人工智能算法的现状。这张图片通过三个同心圆展示了人工智能、机器学习和深度学习之间的包含关系,其中人工智能是最广泛的范畴,机器学习是其子集,专注于数据驱动的算法改进&#…

进程概念、PCB及进程查看

文章目录 一.进程的概念进程控制块(PCB) 二.进程查看通过指令查看进程通过proc目录查看进程的cwd和exe获取进程pid和ppid通过fork()创建子进程 一.进程的概念 进程是一个运行起来的程序,而程序是存放在磁盘的,cpu要想执行程序的指…

OA办公系统自动渗透测试过程

目录 一、下载环境源码 二、部署环境 三、测试 XSS漏洞 SQL注入 文件上传漏洞 一、下载环境源码 OA源码打包地址: https://download.csdn.net/download/weixin_43650289/90434502?spm=1001.2014.3001.5503 二、部署环境

怎么修改node_modules里的文件,怎么使用patch-package修改node_modules的文件,怎么修改第三方库原文件。

在开发中会遇到需要node_modules里第三方库有bug,然后需要修改node_modules文件的情况 使用patch-package包可以修改node_modules里的文件 patch-package npm 官网:patch-package - npm 安装 npm i patch-package 修改文件后 npx patch-package s…

Python在实际工作中的运用-通用格式CSV文件自动转换XLSX

继续上篇《Python在实际工作中的运用-CSV无损转XLSX的几个方法》我们虽然对特定格式的CSV实现了快速转换XLSX的目标,但是在运行Py脚本前,还是需要编辑表格创建脚本和数据插入脚本,自动化程度很低,实用性不强,为减少人工提高效率,实现输入CSV文件路径即可自动适配完成转换…

seacmsv9报错注入

1、seacms的介绍 ​ seacms中文名&#xff1a;海洋影视管理系统。是一个采用了php5mysql架构的影视网站框架&#xff0c;因此&#xff0c;如果该框架有漏洞&#xff0c;那使用了该框架的各个网站都会有相同问题。 2、源码的分析 漏洞的部分源码如下&#xff1a; <?php …

Hbase客户端API——语句大全

目录 创建表&#xff1a; 插入数据&#xff1a; 删除数据&#xff1a; 修改数据&#xff1a; 查询数据&#xff1a;Get 查询数据&#xff1a;Scan 查询数据&#xff1a;过滤查询 创建表&#xff1a; 检验&#xff1a; 插入数据&#xff1a; 验证 一次多条数据插入 验证&…

vscode 版本

vscode官网 Visual Studio Code - Code Editing. Redefined 但是官网只提供最新 在之前的版本就要去github找了 https://github.com/microsoft/vscode/releases 获取旧版本vscode安装包的方法_vscode 老版本-CSDN博客

IP------PPP协议

这只是IP的其中一块内容PPP&#xff0c;IP还有更多内容可以查看IP专栏&#xff0c;前一章内容为网络类型&#xff0c;可通过以下路径查看IP---网络类型-CSDN博客&#xff0c;欢迎指正 3.PPP协议 1.PPP优点 网络类型&#xff1a;p2p PPP---点到点协议 兼容性会更强凡是接口或…

Springboot基础篇(3):Bean管理

前言&#xff1a;Spring 通过扫描类路径&#xff08;Classpath&#xff09;来查找带有特定注解&#xff08;如 Component、Service、Repository 等&#xff09;的类&#xff0c;并将它们注册为 Spring 容器中的 Bean。 1 Bean扫描 Bean 扫描是 Spring 框架的核心功能之一&…

Metal 学习笔记二:3D模型

是什么让一个好游戏更好玩&#xff1f;漂亮的图像&#xff01;就像《神界&#xff1a;原罪2》&#xff0c;《暗黑破坏神3》以及《巫师3》等大作一样&#xff0c;需要一个强大的程序团队以及3D美术团队强强合作。你在屏幕中看到正是3D模型使用自定义渲染绘制的结果。就像上一章你…

【算法】797. 差分

题目 797. 差分 思路 差分的实质是通过构造数组b减少时间复杂度&#xff0c;数组a为初始数据&#xff0c;构造数组b&#xff0c;数组a是b的前缀和&#xff0c;通过对数组b操作就可以实现数组a每个数加上c&#xff0c;而对数组b的操作在单位时间内即可完成&#xff0c;对数组…

解锁状态模式:Java 编程中的行为魔法

系列文章目录 后续补充~~~ 文章目录 一、状态模式&#xff1a;概念与原理二、状态模式的深度剖析&#xff08;一&#xff09;模式定义与核心思想&#xff08;二&#xff09;模式结构与角色 三、状态模式的实际应用场景&#xff08;一&#xff09;电商系统中的订单状态管理&…

php 获取head参数

php 获取head参数 在PHP中&#xff0c;获取HTTP头部&#xff08;head&#xff09;参数可以通过不同的方式实现&#xff0c;下面为你详细介绍几种常见的方法。 1. 使用$_SERVER超全局变量 $_SERVER 是PHP中的一个超全局变量&#xff0c;它包含了诸如头信息、路径、脚本位置等…

数据结构与算法-图论-最短路-拓展运用

选择最佳路线 分析&#xff1a; 这是一道图论中的最短路径问题&#xff0c;目标是在给定的公交网络中&#xff0c;找到从琪琪家附近的车站出发&#xff0c;到她朋友家附近车站&#xff08;编号为 s &#xff09;的最短时间。以下是对该问题的详细分析&#xff1a; 问题关键信息…

AI知识架构之神经网络

神经网络:这是整个内容的主题,是一种模拟人类大脑神经元结构和功能的计算模型,在人工智能领域广泛应用。基本概念:介绍神经网络相关的基础概念,为后续深入理解神经网络做铺垫。定义与起源: 神经网络是模拟人类大脑神经元结构和功能的计算模型,其起源于对生物神经系统的研…

【江科协-STM32】5. 输出比较

1. 输出比较简介 OC(Output Compare)输出比较。 输出比较可以通过CNT&#xff08;CNT计数器&#xff09;与CCR寄存器值的关系&#xff0c;来对输出电平进行置1、置0或翻转的操作&#xff0c;用于输出一定频率和占空比的PWM波形。 :::tip CNT计数器是正向计数器。它只能正向累…