嵌入式系统存储正确性和压力测试方案

描述

本文转自公众号,欢迎关注

嵌入式系统存储正确性和压力测试方案 (qq.com)

前言

在嵌入式系统开发测试阶段通常需要对存储进行正确性和压力测试,比如SRAM,DDR等,通常的做法是进行遍历读写,比如写0x55,0xAA,0x00,0xFF,递增值等这些特殊值然后再回读判断是否正确等,这些测试用例是根据存储的原理和经验等进行总结的。实际上已经有人整理了相应的测试用例https://pyropus.ca./software/memtester/就是一个比较常用的测试代码。

这个代码最新版本是4.6.0,其为Unix类系统上使用设计,这些系统上可以直接安装或者源码编译使用。

移植

为了方便在MCU等环境使用,我将其进行了一些修改,方便移植使用。

https://github.com/qinyunti/memtester_mcu.git

memtester_mcu使用

clone以下仓库https://github.com/qinyunti/memtester_mcu.git,添加代码到自己的目录即可。

参考README.md

实现以下依赖即可:

l:memset

l:rand

l:ULONG_MAX

lmemtester_types.h中需要

l定义几个数据类型,ull位使用,ul为无符号基本数据类型。

typedef unsigned long ul;

typedef unsigned long long ull;

typedef unsigned long volatile ulv;

typedef unsigned char volatile u8v;

typedef unsigned short volatile u16v;

l需实现memtester_printf

然后

#include "memtester.h"

按照如下调用即可

memtester_main((ulv *)0x20004000, 0, 0x2000, 10);

其中0x20004000为待测试存储开始地址,要ul对齐;

第二个参数表示测试用例mask,0表示所有用例都测试;

0x2000为待测试存储区域大小,要ul对齐;

最后10为测试10个循环,压力测试可以将该值写的很大,一直反复测试。

测试用例介绍

memtester_tests.c中一共提供了17个测试用例,下面一一介绍。

有一些辅助函数

compare_regions: 比较两个区域是否一致,按照ulv类型比较

test_stuck_address

测试前先调用该函数遍历测试一下,该函数依次写对应地址的内容为该地址,该地址的内容为该地址的取反,然后下一遍时反过来先写该地址的内容为该地址的取反,然后写对应地址的内容为该地址,然后再回读。

测试第一遍时

比如开始地址为0x20000000基本类型为32位,则0x20000000处的值为0x20000000

0x20000004处的值为0xDFFFFFFB;

测试第二遍时

比如开始地址为0x20000000基本类型为32位,则0x20000000处的值为0xDFFFFFFF

0x20000004处的值为0x20000004;

依此类推共测试16遍。

test_random_value :随机测试

先随机写待测试区域的前面一半和后面一半为同样的值,然后再回读前面一半和后面一半是否一样。

test_xor_comparison :异或随机值测试

将待测试区域前面一半和后面一半的内容(上一个测试的遗留值)都和同一个随机值异或,然后再回读比较。

test_sub_comparison :减随机值测试

将待测试区域前面一半和后面一半的内容(上一个测试的遗留值)都减同一个随机值,然后再回读比较。

test_mul_comparison :乘以随机值测试

将待测试区域前面一半和后面一半的内容(上一个测试的遗留值)都乘以同一个随机值,然后再回读比较。

test_div_comparison:除以随机值测试

将待测试区域前面一半和后面一半的内容(上一个测试的遗留值)都除以同一个随机值,然后再回读比较。

test_or_comparison :或随机值测试

将待测试区域前面一半和后面一半的内容(上一个测试的遗留值)都或上同一个随机值,然后再回读比较。

test_and_comparison :与随机值测试

将待测试区域前面一半和后面一半的内容(上一个测试的遗留值)都与上同一个随机值,然后再回读比较。

test_seqinc_comparison:递增测试

将待测试区域前面一半和后面一半的内容(上一个测试的遗留值)都从同一个随机值开始递增,递增到待测试基本数据的个数,然后再回读比较。

test_solidbits_comparison :固定位测试

将待测试区域前面一半和后面一半的内容依次写0xFFFFFFFF和0x00000000然后再回读比较。

Cesium64轮。

test_checkerboard_comparison :交错位测试

将待测试区域前面一半和后面一半的内容依次写0x55555555和0xAAAAAAAA然后回读测试。

测试64轮。

test_blockseq_comparison :字节递增测试

将待测试区域前面一半和后面一半的内容依次写0x00000000-0x01010101~0x02020202...0xFFFFFFFF这中字节递增,然后回读测试。

test_walkbits0_comparison :1滑动测试

将待测试区域前面一半和后面一半的内容依次写如下值然后回读测试:

共64轮

前面32轮的值

第一轮写0x00000001

第二轮写0x00000002

1往左滑动

后面32轮反向滑动

第32轮写0x80000000

第33轮写0x40000000

test_walkbits1_comparison :0滑动测试

将待测试区域前面一半和后面一半的内容依次写如下值然后回读测试:

共64轮

前面32轮的值

第一轮写0xFFFFFFFE

第二轮写0xFFFFFFFD

0往左滑动

后面32轮反向滑动

第32轮写0x7FFFFFFF

第33轮写0xBFFFFFFF

test_bitspread_comparison :间隔1,0滑动测试

与1滑动类似,只是使用间隔1位的两个1进行滑动

将待测试区域前面一半和后面一半的内容依次写如下值然后回读测试:

共64轮

前面32轮的值

第一轮写

(1<<0) | (1<<2) ~

0xFFFFFFFF ^ (1<<0) | (1<<2)~ 取反

(1<<0) | (1<<2)~ 后面重复

0xFFFFFFFF ^ (1<<0) | (1<<2)

第二轮写 在第一轮基础上滑动

(1<<1) | (1<<3) ~

0xFFFFFFFF ^ (1<<1) | (1<<3)~ 取反

(1<<1) | (1<<3) ~ 后面重复

0xFFFFFFFF ^ (1<<1) | (1<<3)

后面32轮反向滑动

第32轮写

(1<<31) | (1<<33) ~

0xFFFFFFFF ^ (1<<31) | (1<<33)~ 取反

(1<<31) | (1<<33)~ 后面重复

0xFFFFFFFF ^ (1<<31) | (1<<33)

第33轮写 在第一轮基础上滑动

(1<<30) | (1<<32) ~ 取反

0xFFFFFFFF ^ (1<<30) | (1<<32)~ 后面重复

(1<<30) | (1<<32) ~

0xFFFFFFFF ^ (1<<30) | (1<<32)

test_bitflip_comparison :位翻转

32轮

第一轮

重复8次

1<<0,0xFFFFFFFF^(1<<0) 重复到写完缓冲区

第2轮

重复8次

1<<1,0xFFFFFFFF^(1<<1) 重复到写完缓冲区

...

第32轮

重复8次

1<<31,0xFFFFFFFF^(1<<31) 重复到写完缓冲区

test_8bit_wide_random :字节写

将待测试区域前面一半和后面一半的内容分别按照基本类型操作和字节操作方式写入随机值然后回读对比

test_16bit_wide_random :16位写

将待测试区域前面一半和后面一半的内容分别按照基本类型操作和16位操作方式写入随机值然后回读对比

实测

移植比较简单,参考README.md即可,在某个CORTEX-M3的MCU上测试如下

移植

总结

以上测试可以看出

1.尽可能的随机,以避免每次测试都一样,rand还可以先srand一下使得每次测试都不一样。

2.测试相邻位的影响,0x55,0xAA, 全0全0等,比如1和0的滑动,间隔1,0的滑动,位翻转等。

3.遍历到所有的值,比如递增,随机值等。

我们还可以添加总结自己的用例进行完善,实际测试时也可减少一些循环次数加快测试。

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分