0


DDR压力测试工具memtester的源码解读和交叉编译

最近公司的一款产品,核心板上的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

标签: linux 压力测试

本文转载自: https://blog.csdn.net/weixin_44698673/article/details/128238798
版权归原作者 小果壳 所有, 如有侵权,请联系我们删除。

“DDR压力测试工具memtester的源码解读和交叉编译”的评论:

还没有评论