如何在Arm Architecture硬件上进行内存测试?(像Memtest86这样)

Vec*_*tor 8 linux arm

有没有办法在Android设备RAM上进行完整的内存测试?

我正在开发一个驱动程序,但在ramdom时间我得到某些物理地址错误的值导致驱动程序进入错误的状态.当我遇到问题时,我正试图从RAM读取.我认为我设备上某些部分的ram已损坏.

art*_*ise 7

完整是一个含糊不清的词.它可能意味着不同的温度,电压以及具有不同元件容差的一系列器件.当你站点MemTest86时,我想我明白了.我见过的大多数项目都是基于C的,无法测试所有内容.

这是一个在Linux下运行的程序 - http://www.madsgroup.org/~quintela/memtest/

有记录的算法,如行走位等.很大程度上取决于你的RAM类型.我猜你有某种类型的SDRAM.SDRAM有许多不同的周期.有单拍读/写,银行到银行转移,终止突发等.

就个人而言,我们有一个系统,当通过以太网(DMA)进行SSH传输时,5%的电路板会出现问题.SSH涉及加密,这是CPU /内存密集型,DMA引擎通常执行与CPU(带缓存)不同的SDRAM周期.

这是一些要求,

  1. 代码驻留的非SDRAM内存.
  2. 裸金属框架(无缓存,中断,DMA等)
  3. 关闭DCache.
  4. 打开代码的ICache.

另一个限制要求是运行时间.一个完整的 SDRAM测试可能需要几年时间才能在单板上运行.我发现伪随机地址/数据测试效果很好.只需获取与SDRAM大小相关的数字,并将其用作增量.最简单的情况是1.你可能希望找到其他人不断地改变rows,banks和器件尺寸; bank size-1例如; 然而素数会更好,因为你有不同的位数一直在变化.随着缓存关闭,您可以使用char,short,int,和long long指针测试一些不同的突发长度.这些测试会很慢.您将需要使用ldm/stm对来模拟完整的SDRAM突发,这些更常见于缓存,因此您应该使用它们进行模拟ldm/stm.这也是最快的测试之一.

typedef unsigned char      b8;
typedef unsigned short     b16;
typedef unsigned long      b32;
typedef unsigned long long b64;

/* Use a macro to speed code.  The compiler will use constants for
 * _incr and _wrap instead of registers which cause spilling.  A
 * macro centralizes the memory test logic.
 */
#define MEMTEST(name,type,_incr,_wrap) ...

/* Sequential tests. */
MEMTEST(do_mem_seq8,   b8, 97, 1)
MEMTEST(do_mem_seq16, b16, 50839, 1)
MEMTEST(do_mem_seq32, b32, 3999971, 1)
MEMTEST(do_mem_seq64, b64, 3999971, 1)

/* Random tests. These test try to randomize both the data and the
 * address access.
 */

/* 97/0x61 prime for char and 9999991/0x989677 prime for 64MB. */
MEMTEST(do_mem_rnd8,b8,97,9999991)
/* 50839/C697 large prime for 64k and 9999991/0x989677 prime for 64MB. */
MEMTEST(do_mem_rnd16,b16,50839,9999991)
/* 3999971/3D08E3 prime and 9999991/0x989677 prime for 64MB. */
MEMTEST(do_mem_rnd32,b32,3999971,9999991)
/* 3999971/3D08E3 prime and 9999991/0x989677 prime for 64MB. */
MEMTEST(do_mem_rnd64,b64,3999971,9999991)

incr是数据增量,wrap是地址增量.突发的算法将是相同的.这是一些内联gcc汇编程序,

    register ulong t1 asm ("r0")  = 0;                              \
    register ulong t2 asm ("r4")  = t1 + incr;                      \
    register ulong t3 asm ("r6")  = t2 + incr;                      \
    register ulong t4 asm ("r8")  = t3 + incr;                      \
        /* Run an entire burst line. */                             \
        __asm__ (" stmia  %[ptr], {%0,%1,%2,%3}\r\n" : :            \
                 "r" (t1), "r" (t2), "r" (t3), "r" (t4),            \
                 [ptr]"r" (start + (addr<<2)) :                     \
                 "memory" );                                        \
        /* Read four 32 bits values. */                             \
        __asm__ (" ldmia   %[ptr], {%0, %1, %2, %3}\r\n" :          \
                 "=r" (t1), "=r" (t2), "=r" (t3), "=r" (t4) :       \
                 [ptr]"r" (start + (addr<<2)) );                    \
Run Code Online (Sandbox Code Playgroud)

这些测试很简单,应该适合代码缓存,这将最大限度地增加RAM的压力.我们的主要问题是DQS延迟,这对DDR-SDRAM至关重要,可能与温度和电压有关,并且会随PCB布局和材料而变化.

如果您使用SDRAM芯片优化存储器控制器寄存器,则可以使用Cachbench.它也可能对测试有用.

另请参见:Unix Stack Exchange(同一问题).我在Linux下使用了这些基于C的测试套件,但他们没有在我们的案例中暴露任何问题.所述memtest86,在算法可能不如压力(对于PCB毛刺),为我上面描述; 虽然测试7burnBX测试很接近.我认为memtest86可以解决DRAM芯片问题而不是电路板设计问题.

编辑:另一个问题是与SDRAM芯片的瞬态/串扰.如果您的设备驱动程序是高电流或高频设备,SDRAM接口可能会因为电源变化而接收串扰或获得双时钟.因此 RAM测试可能没有问题,SDRAM错误只发生在使用特定硬件部分时.另外请注意,Android设备不使用动态时钟并更改SDRAM频率.当时钟改变时,信号可以穿过共振.