4.5.5. QSPI NAND Flash 压力测试
4.5.5.1. 测试原理
NAND Flash 测试使用 IOzone 工具进行文件系统性能测试,通过执行多种文件操作,如顺序读取、顺序写入、随机读写等,来测试磁盘或存储设备的性能。
测试内容
1. 测试过程:
在使用 iozone 命令测试 NAND Flash 存储设备的性能时,可以通过合理选择测试文件大小、块大小、测试模式和输出格式来更精确地评估其性能。
创建测试文件: IOzone 首先在对应路径上创建一个或多个文件,并会使用特定的块大小来进行读写操作。例如脚本中 IOzone 将会在
$output_dir/iozone_data路径下创建一个大小为 32MB 的测试文件。执行多种 I/O 操作:使用 -a 选项, IOzone 将自动评估多种测试模式和配置,包括不同的块大小、文件大小、操作模式等。
顺序写入( Sequential Write):连续写入数据到存储设备,测试设备的最大写入带宽。
顺序读取( Sequential Read):连续读取数据,测试设备的读取带宽。
随机写入( Random Write):对数据进行随机写入,测试设备的随机写入能力。
随机读取( Random Read):对数据进行随机读取,测试设备的随机读取能力。
不同块大小测试:通过测试不同大小的数据块,可以评估存储设备在不同数据块尺寸下的表现。
覆盖与追加 (Overwrite vs Append):对已经存在的文件进行修改或覆盖,测试设备在更新文件时的性能。
覆盖 (Overwrite):覆盖原有数据,这种方式用于测试设备在处理重复写入时的性能,尤其是对 NAND Flash 存储的影响。
追加 (Append):追加写入数据,不会影响已有数据。
数据记录与分析: IOzone 会记录每个操作的执行时间,并计算吞吐量和延迟等关键指标生成数据报告。
2. 命令解析:
测试命令:
iozone -e -+r -o -a -q 1M -s 32M -f "$output_dir/iozone_data" -Rb "$output_dir/test_iozone_qspi_nand_flash_${loop_num}.xls"参数解析:
-e:计算时间时将 flush (fsync,fflush) 包括进来。
-+r: 这选项是启用 random 模式测试,不仅是顺序读写,还包括随机读写。
-o: 该选项启用 overwrite 测试,测试过程会覆盖文件系统中的数据而不是追加数据。
-a: 启用自动测试模式。这表示 iozone 会在不同的操作模式下自动执行一系列测试,比如顺序读写、随机读写、不同大小的文件等。
-q 1M: 在执行测试时,设置 Iozone 使用的文件块大小为 1MB。
-s 32M: 设置测试的文件大小为 32MB。即, iozone 会在 32MB 大小的文件上执行性能测试。
-f $output_dir/iozone_data:指定测试结果存储的文件路径。
-Rb $output_dir/test_iozone_emmc_ext4_stability_${loop_num}.xls:使用 Excel 格式 (.xls) 输出测试结果文件。
4.5.5.2. 准备工作
1. X5_EVB 默认启动方式为 eMMC,需要将拨码开关切换至 NAND Flash 启动,如图:
拨码开关决定了开发板的启动模式配置、调试串口波特率,方便用户对开发板不同模式的配置,拨码开关内部结构和实物如下图,拨到 ON 位置表明给定信号为高电平 1。

D2、D1、D0三个拨码对应 X5 芯片的2NDBOOT_SEL管脚,用于决定开发板的启动模式。D4拨码对应 X5 芯片的UART_BPS管脚,用于决定开发板调试串口的波特率。
对应的拨码真值表如下表:
| 2NDBOOT_SEL | Value | 选项 | 启动方式的描述 |
|---|---|---|---|
| D2, D1, D0 | 000 | 2NDBOOT UART | 从 UART 接口进行引导启动 |
| 001 | 2NDBOOT eMMC | 从 eMMC 存储设备进行引导启动 | |
| 010 | 2NDBOOT USB2.0 DFU | 从 USB2.0 DFU( Device Firmware Upgrade)接口进行引导启动 | |
| 011 | 2NDBOOT SD Card | 从 SD 卡进行引导启动 | |
| 100 | 2NDBOOT QSPI NOR Flash | 从 QSPI NOR Flash 存储设备进行引导启动 | |
| 101 | 2NDBOOT QSPI NAND Flash | 从 QSPI NAND Flash 存储设备进行引导启动 | |
| 110 | 2NDBOOT USB3.0 DFU | 从 USB3.0 DFU( Device Firmware Upgrade)接口进行引导启动 | |
| 111 | 2NDBOOT QSPI NAND Flash (disable mmu) | 从 QSPI NAND Flash 存储设备进行引导启动,并且在启动时禁用 MMU |
| UART_BPS | Value | 选项 | 描述 |
|---|---|---|---|
| D4 | 0 | 115200bps | 启动时调试串口的波特率将设定为 115200bps |
| 1 | 921600bps | 启动时调试串口的波特率将设定为 921600bps |
2. 准备 NAND Flash 启动的编译镜像,输入 ./bd.sh lunch 选择 4 后,输入 ./bd.sh 进行编译后烧录。
(base) root@DESKTOP-BD9DR0J:/home/gegugu/x5_sdk_default# ./bd.sh lunch
You're building on #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025
Lunch menu... pick a combo:
0. horizon/x5/board_x5_evb_debug_config.mk
1. horizon/x5/board_x5_evb_jammy_debug_config.mk
2. horizon/x5/board_x5_evb_jammy_release_config.mk
3. horizon/x5/board_x5_evb_nand_debug_config.mk
4. horizon/x5/board_x5_evb_nand_release_config.mk
5. horizon/x5/board_x5_evb_release_config.mk
6. horizon/x5/board_x5_soc_debug_config.mk
7. horizon/x5/board_x5_soc_release_config.mk
Which would you like? [0] : 4
3. 需要注意 NAND Flash 启动的镜像里没有 /app 分区,需要将 nand_test.sh 拷贝至 /userdata 路径下 。
可以通过 dmesg 命令查看到,/userdata 路径挂载在 NAND Flash 分区上。
[ 4.930583] ubi1: volume 0 ("userdata") re-sized from 13 to 842 LEBs
[ 4.932256] ubi1: attached mtd9 (name "userdata", size 221 MiB)
[ 4.941166] mtdblock: MTD device 'userdata' is NAND, please consider using UBI block devices instead.
[ 11.830340] UBIFS (ubi1:0): UBIFS: mounted UBI device 1, volume 0, name "userdata"
可以通过命令
cat /proc/mtd查看所有分区大小和所属类型。
dev: size erasesize name
mtd0: 00040000 00040000 "mbr"
mtd1: 00240000 00040000 "miniboot"
mtd2: 00240000 00040000 "miniboot_bak1"
mtd3: 00040000 00040000 "misc"
mtd4: 00200000 00040000 "uboot"
mtd5: 00180000 00040000 "ubootenv"
mtd6: 02000000 00040000 "boot"
mtd7: 09600000 00040000 "system"
mtd8: 06400000 00040000 "hbre"
mtd9: 0dd80000 00040000 "userdata"
4.5.5.3. 测试方法
压测脚本支持输入后缀 -h 查看命令参数的说明,例如:
root@buildroot:/userdata/flash_test# ./nand_test.sh -h
Usage: ./nand_test.sh [options]
Options:
-t <time> Set the test duration ( 2h for hours, 30m for minutes; default: 48h).
-d <seconds> Set the sleep time between loops in seconds (default: 30).
-o <directory> Set the output directory for logs (default: ../log).
-h Show this help message and exit.
各参数解析如下:
-t <time>:设置测试时长,例如 2h 表示 2 小时, 30m 表示 30 分钟,默认是 48 小时。-d <seconds>:设置循环之间的睡眠时间(以秒为单位),默认值是 30 秒。-o <directory>:设置日志输出目录,默认值是脚本所在目录的 ../output 文件夹。-h:显示帮助信息并退出脚本。
示例:
例如,使用命令: ./nand_test.sh -t 2h -d 10 -o /userdata 自定义测试时长 2 小时, 10 秒循环间隔,输出目录为 /userdata 。
确保完成准备工作后,运行测试命令:
chmod +x nand_test.sh
./nand_test.sh
运行一段时间后,打印结果如下:
Iozone: Performance Test of File I/O
Version $Revision: 3.493 $
Compiled for 64 bit mode.
Build: linux
Contributors:William Norcott, Don Capps, Isom Crawford, Kirby Collins
Al Slater, Scott Rhine, Mike Wisner, Ken Goss
Steve Landherr, Brad Smith, Mark Kelly, Dr. Alain CYR,
Randy Dunlap, Mark Montague, Dan Million, Gavin Brebner,
Jean-Marc Zucconi, Jeff Blomberg, Benny Halevy, Dave Boone,
Erik Habbinga, Kris Strecker, Walter Wong, Joshua Root,
Fabrice Bacchella, Zhenghua Xue, Qin Li, Darren Sawyer,
Vangel Bojaxhi, Ben England, Vikentsi Lapa,
Alexey Skidanov, Sudhir Kumar.
Run began: Thu Jan 1 00:31:26 1970
Include fsync in write timing
Read & Write sync mode active.
SYNC Mode.
Auto Mode
Using Maximum Record Size 1024 kB
File size set to 32768 kB
Excel chart generation enabled
Command line used: iozone -e -+r -o -a -q 1M -s 32M -f /userdata/log/iozone_data -Rb /userdata/log/test_iozone_qspi_nand_flash_2.xls
Output is in kBytes/sec
Time Resolution = 0.000001 seconds.
Processor cache size set to 1024 kBytes.
Processor cache line size set to 32 bytes.
File stride size set to 17 * record size.
random random bkwd record stride
kB reclen write rewrite read reread read write read rewrite read fwrite frewrite fread freread
32768 4 2780 4956 1584143 1296151 1103931 4301 1112514 4776 1110629 104392 105451 1532503 1542531
32768 8 5079 9559 1977788 1561719 1547485 10511 1607456 10708 1561273 108863 109577 1927416 1935041
32768 16 9850 20046 2440637 1723633 1978982 19502 2007597 18954 1985097 111847 110092 2271139 2314614
32768 32 17544 36329 2638750 1879761 2318381 31511 2218551 33214 2336732 112556 114307 2599809 2617043
32768 64 33968 70865 2698065 1881812 2456371 64672 2498703 71972 2527419 111349 114829 2679313 2676249
32768 128 58082 109002 2758249 1920300 2571652 108248 2636839 111033 2637900 115383 110742 2732260 2727484
32768 256 71359 104816 2685461 1911116 2609332 105044 2626272 108726 2640876 111676 112701 2705862 2710787
32768 512 79572 103659 2581783 1857701 2562602 106720 2558400 105179 2547857 114214 114433 2466355 2549245
32768 1024 89865 113358 2075237 1701968 2137647 113756 2116385 114655 2128068 113836 111487 1997318 2002811
关键信息说明:
fsync:表示在写入时会同步数据到磁盘,确保数据被持久化。Read & Write sync mode active:读取和写入操作都是同步的。Record Size:使用的最大记录大小为 1024 kB。File size:测试文件的大小为 32768 kB。Excel chart generation enabled:启用了 Excel 图表生成,用于展示结果。Command line used:实际运行的命令是 iozone -e -+r -o -a -q 1M -s 32M -f /userdata/log/iozone_data -Rb /userdata/log/test_iozone_qspi_nand_flash_2.xls。主要性能指标:kB:表示文件大小(单位: KB)。reclen:表示记录大小(单位:字节),即每次读写操作的数据块大小。random write / rewrite / read / reread:这些列分别表示在随机写入、重写、随机读取、重读时的吞吐量。record write / record read:表示记录顺序写入和顺序读取吞吐量。stride read / stride write:表示跳跃读取( stride read)和跳跃写入( stride write)的吞吐量。fwrite / frewrite / fread / freread:这些列表示基于 O_DIRECT 标志进行的直接 I/O 操作的吞吐量。
4.5.5.4. 测试指标
测试程序启动后会在 /userdata/log 目录下生成以下文件:
test_iozone_qspi_nand_flash.log:记录压测时的状态信息。
test_iozone_qspi_nand_flash_*.xls:记录压测时的数据结果。
测试目标是确保系统能够在 48 小时内稳定运行,不发生重启或挂死的情况。为确保测试过程中的稳定性,可通过以下命令检查日志文件中是否存在 fail、 error、 timeout 等异常信息:
cd "/userdata/log/" && grep -iE 'error|fail|timeout' test_iozone_qspi_nand_flash*.log
QSPI NAND Flash 测试结果
运行测试 48H 后检测 log 日志,并未出现异常状态信息,说明 NAND Flash 压测合格。
Test loop 1 succeeded!
Test loop 2 succeeded!
Test loop 3 succeeded!
.....