最近公司的一款产品,核心板上的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-n1 conf-cc)
LD =$(shell head-n1 conf-ld)
可以看到 执行make后 将 conf-cc conf-ld 文件中编译器和链接器的信息赋值给 变量 CC 和 LD
参考:
https://www.cnblogs.com/henjay724/archive/2021/03/25/14560706.html
版权归原作者 小果壳 所有, 如有侵权,请联系我们删除。