内存测试三步法.docx

上传人:牧羊曲112 文档编号:5040357 上传时间:2023-05-31 格式:DOCX 页数:12 大小:138.45KB
返回 下载 相关 举报
内存测试三步法.docx_第1页
第1页 / 共12页
内存测试三步法.docx_第2页
第2页 / 共12页
内存测试三步法.docx_第3页
第3页 / 共12页
内存测试三步法.docx_第4页
第4页 / 共12页
内存测试三步法.docx_第5页
第5页 / 共12页
亲,该文档总共12页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《内存测试三步法.docx》由会员分享,可在线阅读,更多相关《内存测试三步法.docx(12页珍藏版)》请在三一办公上搜索。

1、DDR内存子系统常见硬件错误及Uboot中检测流程在U-Boot中,Denx(U-Boot的开发商)针对常见的DDR 内存故障进行了严格的检测处理,下图描述了该检测处理过程的 三个步骤:检测数据线、地址线和DDR物理存储部件,主要涉 及这三个步骤的处理过程和方法,对于DDR子系统,是很容易 出故障并且是很难debug检测出来的,而Denx所针对DDR 内存故障设计的检测方法是非常严谨,值得学习研究的。D白心 JVfeniOiy T&st1、为什么先检测数据线?因为如果数据线是断开的,那么一切无从谈起!接下来是检测地 址线,只有数据线和地址线都通过,检测内存的存储单元才有意 义,这样的流程也利于

2、分割定位问题。上面testing sequence 框图将整个检测过程分成三大步,用三个虚线方框表示。2、数据线的连接错误数据线的连接可能存在两种错误,一种是被断开,另一种布线或 生产造成互相短路。3、如何检测数据线的连接错误Denx设计的数据线检测算法还是很Tricky和精秒的,整个处 理流程如下例子:如果是两根数据线,只需要写入并读出一个 pattern=0b01(0b开头表示二进制数)就能判断它们是否短 路或断开。很明显,大部分的嵌入式平台不止两根数据线,我们 以 64位地址线为例,pattern = 0b101010101010101010. 能检测出奇偶位之间的数据错误。如果这个错误

3、被排除,每两根 数据线组成一组(这是理解下一个pattern的关键),再用相同 的办法,检测每相邻两组之间是否有短路,就得到第二个pattern,就是0b110011001100 依次类推,以4根数据线为一组,8根线为一组,相继得到共6个pattern,分别是 0xaaaaaaaaaaaaaaaa, 0xcccccccccccccccc,0xf0f0f0f0f0f0f0f0,0xff00ff00ff00ff00,0xffff0000ffff0000,0xffffffff00000000。只要相继写入并读 出这6个pattern就能验证是否存在数据线交叉短路错误。4、如何检测数据线与板上其它信号

4、线交叉短路或断路取以上6个pattern的反码,总共12个pattern就能检测到每 一位都可以写入和读出0和1。5、什么是floating buses错误floating buses会“欺骗测试软件,如果测试软件写入并很快读 出一个值的时候,写操作会给数据线上的电容充电,总线会短暂 的保持它的状态。当测试软件读操作时,总线会返回刚写入的值, 即使实际上该数据线是断路的。6、如何检测数据线的floating buses错误 检测floating buses错误的算法不复杂,在写入和读回之间再 插入一次对不同地址写入不同值的操作。例如,X写入乂1位置,Y写入Y1位置,再从X1位置读出X值则表示f

5、loating buses错 误不存在。7、地址线的错误如果地址线存在错误,其症状是地址空间中的两个不同位置被映 射到同一物理存储位置。更通俗地讲,就是写一个位置却“改变 了另一个位置。8、地址线的错误检测地址线的错误检测相对简单,其算法是:1)、将地址的值作为内容写入该地址处,汇编的表示方法是 (addr) = addr。即将地址值写到地址对应的空间里,这样确保 每一个位置的内容不同。2)、依次将内存基地址的某一根地址线的值翻转flip/toggle) 得到某个地址,从该地址取值,如果该值和基地址的值相等,则 表示某一位地址线有问题。这个算法的特点是每次只检测一根地址线,方法简单有效。9、存

6、储单元的错误以上数据线和地址线的检测都是检测布线或工厂生产的错误,而 存储单元的检测则是真正对DDR内存芯片的检测。内存芯片的 常见错误是bit-stuck,简而言之,就是让它是0,它偏为1,让 它为1,它偏为0,检测方法也很简单,就是用不同的pattern 去写尽可能所有的地址并读回比较。有一些常用的pattern如 0x5555, 0xAAAA 等。10、几个简单的检测DDR故障的方法上面的DDR检测算法,虽然全面,但是耗时比较长,常常需要 好几个小时,在Uboot命令行下也有几个简单的命令可以检测 常见内存故障,如下所示:1)、mtest addr lenth pattern这个命令需要

7、注意,DDR在Uboot启动后被映射到了 0地址, 但是uboot的代码和堆、栈空间0x10000000处开始,这些空 间是不能被刷的,否则就挂死了。2) 、复制NOR flash的内容到内存中,如cp.b 0x200800000x7fc0 20000,然后比较 cmp.b 0x20080000 0x7fc0 20000。3) 、下载 kernel image 到内存中,copy NOR flash 或 tftp 都行,然后调用iminfo LOAD_ADDR检测CRC错误。第一种方法是用特定的pattern去刷DDR的空闲空间,第二种 和第三种方法可以说Pattern的随机性更大一些。当然最

8、彻底的检测方法当然是长时间跑Linux系统,上面的方法 更适用于系统不稳定时定位错误。内存检测方法程序示例static void move64(unsigned long long *src, unsigned long long *dest) *dest = *src;/* This is 64 bit wide test patterns. Note that they reside in ROM* (which presumably works) and the tests write them to RAM which may* not work.* The otherpattern

9、is written to drive the data bus to values other* than the test pattern. This is for detecting floating bus lines.*const static unsigned long long pattern = 0xaaaaaaaaaaaaaaaaULL,0xcccccccccccccccc ULL,0Xf0f0f0f0f0f0f0f0 ULL,0 xff0 0ff0 0ff0 0ff0 0ULL,0xffff00 00ffff0 00 0ULL,0xffffffff00 000 00 0UL

10、L,0x00 00 00 00ffffffffULL,0x0000 ffff0000ffffULL,0x0 0ff0 0ff0 0ff0 0ffULL,0 x 0f0f0f0f0f0f0f0fULL,0x3333333333333333ULL,0x5555555555555555 ULL;const unsigned long long otherpattern = 0x0123456789abcdefULL;/*数据线检测*/static int memory_post_dataline(unsigned long long * pmem)unsigned long long temp64

11、= 0;int num_patterns = sizeof(pattern)/ sizeof(pattern0);int i;unsigned int hi, lo, pathi, patlo;int ret = 0;for ( i = 0; i 32) & 0xffffffff;patio = patterni & 0xffffffff;hi = (temp6432)& oxffffffff;io = temp64 & oxffffffff;post_iog (Memory (date line) error at %08x,wrote %08x%08x, read %08x%08x ! n

12、,pmem, pathi, patio, hi, io);ret = -1;return ret;/*地址线检测*static int memory_post_addriine(uiong *testaddr, uiong *base, uiong size)uiong *target;uiong *end;uiong readback;uiong xor;int ret = 0;end = (uiong *)(uiong)base + size);/* pointer arith! */xor = 0;for(xor = sizeof(uiong); xor 0; xor = base) &

13、 (target end)/*由于target是testaddr某一根地址线的值翻转得来故testaddr != target,下面赋值操作后应有 *testaddr != *target */*testaddr = *target;readback = *target;#ifdef INJECT_ADDRESS_ERRORSif(xor = = 0x00008000)readback = *testaddr;#endif/*出现此种情况只有testaddr = target,即某根地址线翻转无效 * if(readback = = *testaddr)post_log (Memory (ad

14、dress line) error at %08x%08x, XOR value %08x ! n ,testaddr, target, xor);ret = -1;return ret;static int memory_post_test1 (unsigned long start, unsigned long size, unsigned long val)unsigned long i;ulong *mem = (ulong *) start;ulong readback;int ret = 0;for (i = 0; i size / sizeof (ulong); i + +) m

15、emi = val;if (i % 1024 = 0)WATCHDOG_RESET ();for (i = 0; i size / sizeof (ulong) & ret = = 0; i + +) readback = memi;if (readback != val) post_log (Memory error at %08x,wrote %08x, read %08x ! n,mem + i, val, readback);ret = -1;break;if (i % 1024 = 0)WATCHDOG_RESET (); return ret; static int memory_

16、post_ test2 (unsigned long start, unsigned long size) unsigned long i;ulong *mem = (ulong *) start;ulong readback;int ret = 0;for (i = 0; i size / sizeof (ulong); i + +) memi = 1 (i % 32);if (i % 1024 = 0)WATCHDOG_RESET (); for (i = 0; i size / sizeof (ulong) & ret = = 0; i + +) readback = memi;if (

17、readback != (1 (i % 32)刀post_log (Memory error at %08x,wrote %08x, read %08x ! n,mem + i, 1 (i % 32), readback);ret = -1;break;if (i % 1024 = 0)WATCHDOG_RESET (); return ret; static int memory_post_test3 (unsigned long start, unsigned long size) unsigned long i;ulong *mem = (ulong *) start;ulong rea

18、dback;int ret = 0;for (i = 0; i size / sizeof (ulong); i + +) memi = i;if (i % 1024 = 0)WATCHDOG_RESET (); for (i = 0; i size / sizeof (ulong) & ret = = 0; i + +) readback = memi;if (readback != i) post_log (Memory error at %08x,wrote %08x, read %08x ! n,mem + i, i, readback);ret = -1;break;if (i %

19、1024 = 0)WATCHDOG_RESET ();return ret;static int memory_post_test4 (unsigned long start, unsigned long size)unsigned long i;ulong *mem = (ulong *) start;ulong readback;int ret = 0;for (i = 0; i size / sizeof (ulong); i + +) memi = i;if (i % 1024 = 0)WATCHDOG_RESET ();for (i = 0; i size / sizeof (ulo

20、ng) & ret = = 0; i + +) readback = memi;if (readback != i) post_log (Memory error at %08x,wrote %08x, read %08x ! n,mem + i, i, readback);ret = -1;break;if (i % 1024 = 0)WATCHDOG_RESET (); return ret; static int memory_post_ tests (unsigned long start, unsigned long size) int ret = 0;if (ret = = 0)r

21、et = memory_post_dataline (unsigned long long *)start);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_addrline (ulong *)start, (ulong *)start, size);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_addrline (ulong *)(start + size - 8), (ulong *)start, size);WATCHDOG_RESET ();if (ret = = 0)ret =

22、memory_post_test1 (start, size, 0x00000000);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_test1 (start, size, 0xffffffff);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_test1 (start, size, 0x55555555);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_test1 (start, size, 0xaaaaaaaa);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_test2 (start, size);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_test3 (start, size);WATCHDOG_RESET ();if (ret = = 0)ret = memory_post_test4 (start, size);WATCHDOG_RESET ();return ret;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号