Edit online

测试指南

27 Nov 2024
Read time: 10 minute(s)

测试环境

准备 SDMC 测试所需的测试环境,如下所示:
  • 硬件
    • 开发板,或者 FPGA 板子

    • 板子上必须要接有 eMMC/SDCard

  • 软件
    • PC 端的串口终端软件,用于 PC 和开发板进行串口通信

    • Linux 内核原生的 test 工具,用于 Host 驱动的功能测试

    • Luban 自带的 iozone 工具,用于块设备的性能测试

按照下列步骤打开对应的测试工具:
  • mmc_test
    在 Luban 根目录下执行 make kernel-menuconfig,进入 kernel 的功能配置,按如下选择:
    Linux
        Device Drivers
            <*> MMC/SD/SDIO card support
                < >   MMC block device driver
                <*>   MMC host test driver
    注: mmc_test 必须要关闭 Block 选项,否则 test 模块不会被内核加载。
  • iozone
    在 Luban 根目录,运行 menuconfig,按如下选择:
    Third-party packages
        [*] iozone

mmc_test 测试

mmc_test 的主要功能是测试符合 MMC 子系统的 Host 驱动功能,源码详见 driversmmccoremmc_test.c

按照下列步骤,执行 mmc_test 测试:

  1. 打开 mmc_test 功能
    注: mmc_test 必须要关闭 Block 选项,否则 test 模块不会被内核加载。
    在 Luban 根目录下执行 make kernel-menuconfig,进入 kernel 的功能配置,按如下选择:
    Linux
        Device Drivers
            <*> MMC/SD/SDIO card support
                < >   MMC block device driver
                <*>   MMC host test driver
  2. 板子在启动到 Shell 后,挂载 debugfs 文件系统,并查看 test 的测试节点:

    test_wdt 的帮助信息:
    [aic@] # mount -t debugfs none /sys/kernel/debug/
    [aic@] # cd /sys/kernel/debug/mmc0/mmc0\:0001/
    [aic@mmc0:0001] # ls
    state     test      testlist
    [aic@mmc0:0001] # cat testlist # 此时会打印测试选项
    0:      Run all tests
    1:      Basic write (no data verification)
    2:      Basic read (no data verification)
    3:      Basic write (with data verification)
    4:      Basic read (with data verification)
    5:      Multi-block write
    6:      Multi-block read
    7:      Power of two block writes
    8:      Power of two block reads
    9:      Weird sized block writes
    10:     Weird sized block reads
    11:     Badly aligned write
    12:     Badly aligned read
    13:     Badly aligned multi-block write
    14:     Badly aligned multi-block read
    15:     Correct xfer_size at write (start failure)
    16:     Correct xfer_size at read (start failure)
    17:     Correct xfer_size at write (midway failure)
    18:     Correct xfer_size at read (midway failure)
    19:     Highmem write
    20:     Highmem read
    21:     Multi-block highmem write
    22:     Multi-block highmem read
    23:     Best-case read performance
    24:     Best-case write performance
    25:     Best-case read performance into scattered pages
    26:     Best-case write performance from scattered pages
    27:     Single read performance by transfer size
    28:     Single write performance by transfer size
    29:     Single trim performance by transfer size
    30:     Consecutive read performance by transfer size
    31:     Consecutive write performance by transfer size
    32:     Consecutive trim performance by transfer size
    33:     Random read performance by transfer size
    34:     Random write performance by transfer size
    35:     Large sequential read into scattered pages
    36:     Large sequential write from scattered pages
    37:     Write performance with blocking req 4k to 4MB
    38:     Write performance with non-blocking req 4k to 4MB
    39:     Read performance with blocking req 4k to 4MB
    40:     Read performance with non-blocking req 4k to 4MB
    41:     Write performance blocking req 1 to 512 sg elems
    42:     Write performance non-blocking req 1 to 512 sg elems
    43:     Read performance blocking req 1 to 512 sg elems
    44:     Read performance non-blocking req 1 to 512 sg elems
    45:     Reset test
    46:     Commands during read - no Set Block Count (CMD23)
    47:     Commands during write - no Set Block Count (CMD23)
    48:     Commands during read - use Set Block Count (CMD23)
    49:     Commands during write - use Set Block Count (CMD23)
    50:     Commands during non-blocking read - use Set Block Count (CMD23)
    51:     Commands during non-blocking write - use Set Block Count (CMD23)us
  3. 根据需求,选一个测试项,将其编号写入 mmc_test 节点,如使用测试项 1:
    [aic@mmc0:0001] # echo 1 > test
    [  162.185679] mmc0: Starting tests of card mmc0:0001...
    [  162.190820] mmc0: Test case 1. Basic write (no data verification)...
    [  162.209563] mmc0: Result: OK
    [  162.212462] mmc0: Tests completed.
    为了方便测试,可以通过以下脚本 批量运行完所有的 mmc_test 测试项:
    #!/bin/sh
    
    run_one_testcase()
    {
        echo $1 > test
        if [ $? -ne 0 ]; then
            echo ERROR: Testcase $i failed!
            exit 110
        fi
    }
    
    run_memtest()
    {
    
        echo Prepare the debugfs ...
        mount -t debugfs none /sys/kernel/debug/
        cd /sys/kernel/debug/mmc0/mmc0:0001
    
        echo
        echo Run memtest ...
        echo
    
        CNT=1
        while true
        do
            echo
            echo ----------------------------------------------------------
            echo Run all the testcase, count $CNT ...
            echo ----------------------------------------------------------
    
            echo
            echo Run in order sequence ...
            echo
    
            for i in `seq 0 51`;
            do
                run_one_testcase $i
            done
    
            echo
            echo Run in random sequence ...
            echo
    
            for i in `seq 0 51`;
            do
                $TMP=`expr $RANDOM % 52`
                run_one_testcase $TMP
            done
    
            CNT=`expr $CNT + 1`
        done
    }
    
    run_memtest()

iozone 测试

  1. iozone
    在 Luban 根目录,运行 menuconfig,按如下选择:
    Third-party packages
        [*] iozone
  2. iozone 测试需要用到块设备,必须要将内核中的 MMC Block 打开:
    Linux
        Device Drivers
            <*> MMC/SD/SDIO card support
                <*>   MMC block device driver
    
  3. 除了执行性能测试外,iozone 还可以用作稳定性测试,只需使用脚本长时间循环运行 iozone 测试即可。

    详细的测试步骤如下所示:
    1. 将 MMC 或 SDCard 块设备格式化为 ext4 文件系统。
    2. 将格式化后的块设备挂载到一个特定路径。
    3. 在该路径中运行 iozone 工具。

      iozone 运行过程中会在当前目录下创建一个临时文件,该文件的大小会根据测试数据粒度而自动调整。

    注: iozone 支持将性能数据作为结果存储到一个 Excel 文件中,方便查看。
    以下是调用 iozone 的循环测试脚本:
    #!/bin/sh
    
    if [ ! -z $1 ] && [ ! -z $2 ]; then
        FILE_MIN_SIZE=$1
        FILE_MAX_SIZE=$2
    else
        FILE_MIN_SIZE=16m
        FILE_MAX_SIZE=128m
    fi
    
    RESULT_FILE=iozone_result.xls
    TMP_FILE=iozone.tmp
    
    run_cmd()
    {
        echo
        echo $1
        echo
        eval $1
    }
    
    mount_mmc()
    {
        HOSTNAME=`hostname`
        if [ $HOSTNAME = "Artinchip" ]; then
            WORKSPACE_DIR=/mnt/sdcard
            MMC_DEV=/dev/mmcblk0p9
    
            echo Mount $MMC_DEV ...
            if [ "$1" != "debug" ]; then
                # mkfs.vfat $MMC_DEV 2048000
                mount -t vfat $MMC_DEV $WORKSPACE_DIR
            fi
            if [ $? -ne 0 ]; then
                echo ERR: Failed to mount $MMC_DEV
                exit 100
            fi
        else
            WORKSPACE_DIR=./mnt/sdcard
            echo Use the local path: $WORKSPACE_DIR
        fi
    }
    
    mount_udisk()
    {
        WORKSPACE_DIR=/mnt/usb
        UDISK_DEV=/dev/sda1
    
        echo Mount $UDISK_DEV ...
        mount -t vfat $UDISK_DEV $WORKSPACE_DIR
        if [ $? -ne 0 ]; then
            echo ERR: Failed to mount $UDISK_DEV
            exit 100
        fi
    }
    
    mount_mtd()
    {
        WORKSPACE_DIR=/mnt/mtd
        if [ ! -d $WORKSPACE_DIR ]; then
            mkdir -p $WORKSPACE_DIR
        fi
    }
    
    umount_all()
    {
        cd -
        umount -f $WORKSPACE_DIR
    }
    
    check_stop()
    {
        echo
        echo Press \'any key\' + \'EnterKey\' to stop testing
        read -t 5 CMD
        if [ ! -z $CMD ]; then
            umount_all
            exit 100
        fi
    }
    
    if [ -b /dev/sda ]; then
        mount_udisk
    elif [ -b /dev/mmcblk0 ]; then
        mount_mmc $1
    elif [ -c /dev/mtd0 ]; then
        mount_mtd
    else
        echo There is no block device in the board!
        exit 110
    fi
    
    echo Enter workspace $WORKSPACE_DIR
    cd $WORKSPACE_DIR
    
    CNT=1
    while true
    do
        echo
        echo ----------------------------------------------------------
        echo iozone test, count $CNT
        echo ----------------------------------------------------------
        date
    
        run_cmd "iozone -a -V -n $FILE_MIN_SIZE -g $FILE_MAX_SIZE -q 16m -w -b $RESULT_FILE -f $TMP_FILE"
    
        check_stop
    
        CNT=`expr $CNT + 1`
    done