5.1.4. 测试指南

5.1.4.1. 测试环境

5.1.4.1.1. 硬件

  • 开发板

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

5.1.4.1.2. 软件

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

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

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

5.1.4.1.3. 软件配置

5.1.4.1.3.1. mmc_test

参考快速入门 - 编译概述 - Kernel配置,进入kernel的功能配置,按如下选择:

Linux
    Device Drivers
        <*> MMC/SD/SDIO card support
            < >   MMC block device driver
            <*>   MMC host test driver

备注

mmc_test必须要关闭MMC Block选项,否则mmc_test模块不会被内核加载。

5.1.4.1.3.2. iozone

在openwrt根目录,运行make menuconfig,按如下选择:

Third-party packages
    [*] iozone

5.1.4.2. mmc_test 测试

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

板子在启动到shell后,首先要挂载debugfs文件系统,然后可以查看mmc_test的测试节点:

[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

根据需求,选一个测试项,将其编号写入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()

5.1.4.3. iozone测试

iozone测试需要用到块设备,必须要将内核中的MMC Block打开:

Linux
    Device Drivers
        <*> MMC/SD/SDIO card support
            <*>   MMC block device driver

iozone本身是用来做性能测试,如果使用脚本长时间的循环运行就可用于稳定性测试。

测试步骤:

  1. 格式化MMC块设备/SDCard块设备为ext4文件系统;

  2. 将格式化后的块设备挂载到某个路径;

  3. 在上述路径中运行iozone工具即可。

小技巧

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

  2. 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 = "ZX" ]; 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