最近公司的一款产品,核心板上的DDR由工业级的降为民用的,程序运行过程中容易出现内存泄漏的问题。所以再产品测试流程中增加DDR的压力测试。
使用最流行的开源工具 memtester 但是memtester默认测试循环次数太多,完成一次压力测试需要20多分钟不利于生产测试,于是需要修改源码,从新编译。
1、下载源码
源码下载地址
2、使用方法及原理
3、源码分析
源文件结构
\memtester-4.5.0
\memtester.h
\memtester.c --主程序入口
\sizes.h --关于系统位数(32/64bit)的一些定义
\types.h --所用数据类型的定义
\tests.h
\tests.c --测试算法子程序
主程序分析
struct test {
char *name;
int (*fp)();
};
// 各个测试函数定义在tests.c中
struct test tests[] = {
{ "Random Value", test_random_value },
{ "Compare XOR", test_xor_comparison },
{ "Compare SUB", test_sub_comparison },
{ "Compare MUL", test_mul_comparison },
{ "Compare DIV",test_div_comparison },
{ "Compare OR", test_or_comparison },
{ "Compare AND", test_and_comparison },
{ "Sequential Increment", test_seqinc_comparison },
{ "Solid Bits", test_solidbits_comparison },
{ "Block Sequential", test_blockseq_comparison },
{ "Checkerboard", test_checkerboard_comparison },
{ "Bit Spread", test_bitspread_comparison },
{ "Bit Flip", test_bitflip_comparison },
{ "Walking Ones", test_walkbits1_comparison },
{ "Walking Zeroes", test_walkbits0_comparison },
#ifdef TEST_NARROW_WRITES
{ "8-bit Writes", test_8bit_wide_random },
{ "16-bit Writes", test_16bit_wide_random },
#endif
{ NULL, NULL }
};
/* Function definitions */
void usage(char *me) {
fprintf(stderr, "\n"
"Usage: %s [-p physaddrbase [-d device]] <mem>[B|K|M|G] [loops]\n",
me);
exit(EXIT_FAIL_NONSTARTER);
}
int main(int argc, char **argv) {
ul loops, loop, i;
size_t bufsize, halflen, count;
void volatile *buf, *aligned;
ulv *bufa, *bufb;
ul testmask = 0;
// 省略若干变量定义代码
printf("memtester version " __version__ " (%d-bit)\n", UL_LEN);
printf("Copyright (C) 2001-2020 Charles Cazabon.\n");
printf("Licensed under the GNU General Public License version 2 (only).\n");
printf("\n");
// 省略若干初始检查代码
// 从输入参数里获取physaddrbase计算出内存测试起始地址aligned
// 从输入参数里获取mem及B|K|M|G计算出内存测试总长度bufsize
halflen = bufsize / 2;
count = halflen / sizeof(ul);
bufa = (ulv *) aligned;
bufb = (ulv *) ((size_t) aligned + halflen);
// 压力测试的重要变量, loops即重复次数
for(loop=1; ((!loops) || loop <= loops); loop++) {
printf("Loop %lu", loop);
if (loops) {
printf("/%lu", loops);
}
printf(":\n");
printf(" %-20s: ", "Stuck Address");
fflush(stdout);
// 第一个测试 stuck_address
if (!test_stuck_address(aligned, bufsize / sizeof(ul))) {
printf("ok\n");
} else {
exit_code |= EXIT_FAIL_ADDRESSLINES;
}
// 遍历tests.c里的所有测试子程序
for (i=0;;i++) {
if (!tests[i].name) break;
if (testmask && (!((1 << i) & testmask))) {
continue;
}
printf(" %-20s: ", tests[i].name);
// 可以看到将内存测试总空间一分为二,传给子程序做处理的
if (!tests[i].fp(bufa, bufb, count)) {
printf("ok\n");
} else {
exit_code |= EXIT_FAIL_OTHERTEST;
}
fflush(stdout);
/* clear buffer */
memset((void *) buf, 255, wantbytes);
}
printf("\n");
fflush(stdout);
}
}
4、修改源码
- count = halflen / sizeof(ul);
+ count = halflen / sizeof(ul) /4; //经过调试 将循环次数除以4得到合理的测试时间
5、编译源码
修改 conf-cc 文件,将 cc 修改为arm-linux-gnueabihf-gcc 添加 -static (静态编译参数)
如下:
arm-linux-gnueabihf-gcc -static -O2 -DPOSIX -D_POSIX_C_SOURCE=200809L -D_FILE_OFFSET_BITS=64 -DTEST_NARROW_WRITES -c
修改 conf-ld 文件,将 cc 修改为arm-linux-gnueabihf-gcc 添加 -static (静态编译参数)
如下:
arm-linux-gnueabihf-gcc -static -s
执行 make 编译源码 可以看到生成一个叫 memtester的可执行文件。
扩展:
查看makefile文件
CC = $(shell head -n 1 conf-cc)
LD = $(shell head -n 1 conf-ld)
可以看到 执行make后 将 conf-cc conf-ld 文件中编译器和链接器的信息赋值给 变量 CC 和 LD文章来源:https://www.toymoban.com/news/detail-506345.html
参考:
https://www.cnblogs.com/henjay724/archive/2021/03/25/14560706.html文章来源地址https://www.toymoban.com/news/detail-506345.html
到了这里,关于DDR压力测试工具memtester的源码解读和交叉编译的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!