SD EMMC Stress Test SOP

REVISION HISTORY

Revision No. Description Date
1.0
  • Initial release
  • 05/08/2023

    1. SD EMMC压力测试介绍

    1.1. 概述

    本文用于指导在SOC emmc boot下对sd/emmc存储进行读写以及擦除的压力测试,主要是通过fio工具及相关的测试接口来对sd/emmc进行读写及擦除测试,并希望以此能够暴露出sd/emmc潜在的问题,判断sd/emmc的健康情况。

    1.2. 测试前环境准备

    注:Linux emmc boot环境和android环境,默认已经打开了emmc drivers。

    1.2.1. Kernel driver

    测试前需要确保内核支持emmc driver。

    安卓系统可以不打开HW reset support for eMMC和Simple HW reset support for MMC两个选项。

    Location:
    ​    -> Device Driver
    ​       -> MMC/SD/SDIO card support
    

    对应的kernel config配置为:

    SD 压测需要打开kernel 的Sigmastar sd driver选项:

    安卓系统编译成module的话编译出的ko为kdrv_sdmmc.ko

    Location:
    ​    -> Device Driver
    ​       -> SStar SoC platform drivers
    ​           ->SStar SD/MMC Card Interface Support
    

    对应的kernel config配置为:

    将上述内核选项开启后升级开发板,再进行下一步动作。

    1.2.2. 开发板环境

    1. 命令检查

      测试需要使用到fio工具,linux平台tipcode已包含fio工具,安卓平台可使用以下提供的文件(可右键复制,粘贴到目录中):

      fio-android32

      fio-android64

    2. 驱动检查

      按照2.1描述的打开驱动并升级后,检查开发板SD和EMMC对应的块设备文件(/dev/mmcblk0或/dev/mmcblk1)和/sys/bus/platform/devices/soc:emmc/eMMC_erase_test测试接口文件(不测试emmc擦除则不用这个文件)是否存在,不存在需要在编译代码前后检查内核相关选项是否开启。

    3. 测试分区

      若需要进行emmc擦除测试,建议单独创建分区进行测试。

      新建分区方式:

      测试者可以在uboot下可以使用emmc creat命令创建测试分区,例:

      emmc create test1 0x82900000 //创建一个大小为2G,名称为test1的emmc分区
      

      使用mmc part查看新建的分区:

      可以看到分区test1的分区号为7,在kernel下对应的测试分区文件为/dev/mmcblk0p7

    1.3. FIO读写测试

    测试前挂载需要测试的分区。以SD为例,若SD卡的块设备文件为/dev/mmcblk1,可通过以下方式挂载:

    mkfs.fat /dev/mmcblk1     //以fat文件系统格式化SD卡
    
    mount /dev/mmcblk1 /mnt/   //挂载SD卡到/mnt/目录
    

    使用FIO工具对sd/emmc进行读写测试,包含顺序写、顺序读、随机写和随机读四种方式。测试前在所测试的分区中创建测试文件(如emmc_test),注意使用FIO进行测试时,分区所预留的空间需要大于设置的读写数据量,建议测试的数据量大小大于1G。

    参数bs和size可根据用户需求自行设置,其它参数按下面指定即可。

    1.3.1. FIO参数说明

    filename=/mnt/emmc_test    #测试文件名称(填绝对路径)。
    direct=1        #是否使用directIO,测试过程绕过系统自带的buffer。
    rw=randread     #测试随机读的I/O
    rw=randwrite    #测试随机写的I/O
    rw=read         #测试顺序读的I/O
    rw=write        #测试顺序写的I/O
    bs=512          #单次IO的块文件大小为512字节
    size=1G         #每个线程读写的数据量为1GB。
    name=mytest     #当前指令任务的名字
    thread          #使用pthread_create创建线程,另一种是fork创建进程。进程的开销比线程要大,一般都采用thread测试。
    ioengine=psync   #指定IO引擎使用psync方式。
    -numjobs=4       #本次测试的线程数是4
    -group_reporting     #显示任务的测试结果
    

    1.3.2. FIO顺序写测试

    使用以下指令进行测试:

    (1)测试单次写的块IO大小为512字节,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=write -ioengine=psync -bs=512 -size=1G -numjobs=4 -group_reporting -name=mytest
    

    (2)测试单次写的块IO大小为1M,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=write -ioengine=psync -bs=1M -size=1G -numjobs=4 -group_reporting -name=mytest
    

    1.3.3. FIO顺序读测试

    使用以下指令进行测试:

    (1)测试单次读的块IO大小为512字节,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=read -ioengine=psync -bs=512 -size=1G -numjobs=4 -group_reporting -name=mytest
    

    (2)测试单次读的块IO大小为1M,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=read -ioengine=psync -bs=1M -size=1G -numjobs=4 -group_reporting -name=mytest
    

    1.3.4. FIO随机写测试

    使用以下指令进行测试:

    (1)测试单次写的块IO大小为512字节,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=randwrite -ioengine=psync -bs=512 -size=1G -numjobs=4 -group_reporting -name=mytest
    

    (2)测试单次写的块IO大小为1M,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=randwrite -ioengine=psync -bs=1M -size=1G -numjobs=4 -group_reporting -name=mytest
    

    1.3.5. FIO随机读测试

    使用以下指令进行测试:

    (1)测试单次读的块IO大小为512字节,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=randread -ioengine=psync -bs=512 -size=1G -numjobs=4 -group_reporting -name=mytest
    

    (2)测试单次读的块IO大小为1M,数据大小为1G

    fio -filename=/mnt/emmc_test -direct=1 -thread -rw=randread -ioengine=psync -bs=1M -size=1G -numjobs=4 -group_reporting -name=mytest
    

    1.3.6. FIO测试结果分析

    可忽略报错:

    fio:cache invalidation of /mnt/emmc_test fail:Invalid argument
    

    测试结果举例:

    测试者主要关注红色方框内的几个参数数据是否异常:

    cpu: 用户(usr)时间和系统(sys)时间的占比

    bw: 总带宽(a),最小带宽(b)和最大带宽©,这里均为202M/S。(括号内是10的幂的形式)

    io: 该组中所有线程执行的累计I/O大小(d),这里四个线程累计写4096M(括号内是10的幂的形式)

    run: 这组线程中最小和最长的运行时间(e),这里运行时间为20.26秒

    1.3.7. CPU加压测试

    除了上述常规FIO测试外,可模拟CPU忙碌状态下进行FIO测试。

    cpu_loading使用方式:

    echo “loading 0 80 4” > /sys/devices/virtual/mstar/msys/cpu_loading
    

    参数说明:

    • 第一个%d表示总的运行毫秒数,当输入为0时,表示没有时间限制

    • 第二个%d表示需要的%CPU占用数值(0< num <= 100: 以毫秒为单位,占用一毫秒内的百分比时间,余下时间休眠)

    • 第三个%d表示是否开启运行及运行模式(测试时候使用4,为0时表示关闭程序运行)

    注:多核情况下,使用top命令查看展示的%CPU是多核的平均值,需要乘以核数才是单核CPU的实际占用率。

    Cpu占用率可根据用户业务实际情况自行设置,模拟CPU忙碌时,FIO读写emmc是否正常。可开启cpu_loading之后再进行FIO读写测试。

    1.3.8. BIST拉频宽测试

    除了章节3.7描述的CPU加压测试外,可以开启BIST来进行DDR的加压测试。

    BIST使用方式:

    echo miu_bist on MIU_BIST_ALL 1 > /proc/mi_modules/mi_sys/mi_sys0
    

    通过上述命令bist将最大限度占用访问DDR的频宽,可以在此模式下进行FIO测试

    关闭BIST:

    echo miu_bist on MIU_BIST_OFF > /proc/mi_modules/mi_sys/mi_sys0
    

    1.4. EMMC擦除测试

    擦除测试会擦除分区数据,建议单独创建分区进行测试,分区创建方法见章节2.2,如果不想创建新分区可以不进行擦除测试。

    eMMC_erase_test使用方式:

    echo "0 0x5AEC00 0x414800" > /sys/bus/platform/devices/soc:emmc/eMMC_erase_test
    

    参数说明:

    • 第一个%d是emmc设备的slot number,P5板子这里为0

    • 第二个%x表示分区的起始地址,单位是块(十六进制)

      注:可以通过cat /sys/block/mmcblk0/mmcblk0p7/start命令获取分区起始地址

    ​ 用计算器将5958656转换为16进制为0x5AEC00

    • 第三个%x表示要擦除的大小,单位是块(十六进制)

      注:这里0x414800表示擦除整个分区,分区大小可以通过cat /sys/block/mmcblk0/mmcblk0p7/size命令获取。

    ​ 用计算器将4278272转换为16进制为0x414800

    若需要反复进行擦除测试可以每次擦除前重新格式化分区,保证擦除动作会被emmc设备执行。格式化方式:mkfs.ext4 /dev/mmcblk0p7,过程中输入y即可。

    1.5. vbs脚本监控测试结果

    若测试者需要自动监控压测结果是否正常可以使用xshell运行下面所提供的vbs监控脚本:

    Sub Main
        Dim waitStrs, result
        Dim i, testCount
    
        i = 0
        testCount = 172800 '48h'
        waitStrs = Array("eMMC_FCIE_DumpRegisters")
    
        Do While i < testCount
    
            result = xsh.Screen.WaitForStrings(waitStrs, 1000)
            If result = 1 Then
                xsh.Screen.Send chr(3)
                xsh.Screen.Send(VbCr)
                xsh.Screen.Send("ps w | grep emmc_stress_test | grep -v ""grep"" | awk '{printf $1}' | xargs kill >/dev/null 2>&1")
                xsh.Screen.Send(VbCr)
                xsh.Screen.Send(VbCr)
                xsh.Screen.Send("emmc stress test fail!")
                exit sub
            else
                i = i + 1
            End If
        Loop
    
        xsh.Screen.Send chr(3)
        xsh.Screen.Send(VbCr)
        xsh.Screen.Send("ps w | grep emmc_stress_test | grep -v ""grep"" | awk '{printf $1}' | xargs kill >/dev/null 2>&1")
        xsh.Screen.Send(VbCr)
        xsh.Screen.Send(VbCr)
        xsh.Screen.Send("emmc stress test success.")
    End Sub
    

    使用者可以根据需要修改脚本中的测试时间(若是SD压测将脚本中的“eMMC_FCIE_DumpRegisters”修改为“DumpReg”),若压测脚本在后台运行,运行前将压测脚本重命名为emmc_stress_test.sh,vbs监控脚本最后会停止压测脚本运行。

    压测开始前运行此脚本,打开xshell的工具选项,选择要运行的脚本文件:

    脚本运行后会监控压测过程中驱动是否报出eMMC_FCIE_DumpRegisters相关错误,检查到此错误后会停止压测,打印“emmc stress test fail!”,若是监控时间内没有检查到错误,最后也会停止压测并打印“emmc stress test success.”


    2. eMMC 掉电保护压力测试介绍

    2.1. 概述

    本章节用于指导eMMC Power Save Mode(PSM)功能压测,模拟实际应用场景,在压测环境下,配合随机上下电,检验系统稳定性,全过程自动化进行。

    2.2. 测试环境准备

    2.2.1 硬件环境

    • evb/demo开发板(需要将SAR1 pin放通以支持SAR detect功能)

    • 继电器控制模块

    • 2个12V电源适配器(一个给开发板供电;另一个给继电器控制模块供电)

    • 1个串口模块

    2.2.2 测试原理

    • fio工具进行顺序读写

    • python serial模块编程控制继电器随机上下电

    • eMMC驱动掉电保护功能

    2.3. 测试步骤

    2.3.1 pure linux

    • 拉取tipcode,并编译镜像,不再赘述,P5请使用emmc boot方式

    • 烧录完镜像后,重新回到uboot,创建test分区,大概4GB左右,如图:

    • 重新进入kernel后,将新创建的分区格式化为ext4文件系统格式,挂载点为/mnt

    • 挂载好test分区后,配置网络参数信息,进入/mnt路径,将emmc掉电压测.zip附件中的testcheck.sh脚本和fio文件(使用fio_linux并重命名为fio)加载到路径中。记得dos2unix testcheck.sh并且同时给fio和testcheck.sh赋予执行权限+x

    • 更改/etc/init.d/rcS如下,使得每次下电上电后可以自动执行压测脚本

    2.3.2 Android

    • 拉取tipcode,并编译镜像,不再赘述,请参考[android环境编译手册]

    • 镜像编译完,正常按照[android刷机流程],烧录镜像即可,注意烧录前,uboot中先执行mmc erase并且reset重新进入uboot,可以采用网络或usb方式,利用adb工具烧录。

    • 烧录完成后,重新进入uboot,配置selinux=0 androidboot.selinux=permissive并saveenv(由于android环境selinux权限问题复杂,压测时先关闭)

    • 设置完环境变量后,reset重新进入kernel,执行cat /proc/cmdline确认设置是否成功

    • 配置网络参数,及adbd port参数

    • 在PC端,使用adbd客户端连上开发板,需要以root权限登录并remount以便操作文件

    • 登录成功后,通过adb下载/vendor/bin/init.insmod.sh脚本,并按图在脚本最后变更内容后,重新上传

    • 上传testcheck.sh脚本到/vendor/bin路径(在附件emmc_android掉电测试.zip中获取)

    • 创建/data/test路径,并且上传fio文件到此路径,chmod 755 fio赋予执行权限

      至此,所有准备工作已经完成,sync;reboot即可

    • 在Android环境,可以通过logcat | grep eMMC查阅压测日志打印

    2.3.3 随机上下电

    附件中的serialControl.py为控制继电器随机上下电的python脚本,直接在PC端执行即可:python serialControl.py。通电时间为[10s, 600s]区间内的整数。唯一需要注意的是,脚本中的端口号,需要根据接入PC时,继电器控制器实际分配为准。

    2.4. 测试结果

    • 测试持续时长可以根据实际情况自行决定

    • 如果压测过程出现异常,会输出error log,并且保留问题现场

    2.5. 附件

    emmc掉电压测.zip

    emmc_android掉电压测.zip