我正在自定义板上工作,包括32位单片机( A5)和16位宽DRAM芯片(LPDDR2)。单片机有一个支持DDR3和LPDDR2的车载DRAM控制器,我确实有一个使用LPDDR2的工作设置。
现在,由于电源限制,我试图在启动时将MCU和DRAM (它们都使用相同的PLL)的时钟速率减半,这就是我的麻烦所在。
如前所述,我确实有一个使用全频率的工作设置( DRAM : 400 the,MCU: 396 the ),因此人们会期望将频率减半并根据DRAM数据表更新时间应该会产生另一个工作设置,但没有。
DRAM init在启动时从MCU内部运行,任何测试也是如此。整个过程由一个特定于董事会的U-Boot 2015.04版本来处理.
我有一个测试集合,运行在MCU启动,以验证DRAM的完整性。其中一个测试是所谓的“步行位”-test,其中我使用了一个32位的uint,按顺序切换每一个位,然后读取以进行验证。
我发现,当读回来的时候,下面的16位没有被触摸,而上面的16位似乎被改变了。经过一些调查,我发现了以下模式(假设水印为"0xaa"):
write -> readback
0x8000_0000 -> 0x0000_aaaa
0x4000_0000 -> 0x0000_aaaa
0x2000_0000 -> 0x0000_aaaa
0x1000_0000 -> 0x0000_aaaa
[...]
0x0008_0000 -> 0x0000_aaaa
0x0004_0000 -> 0x0000_aaaa
0x0002_0000 -> 0x0000_aaaa
0x0001_0000 -> 0x0000_aaaa
0x0000_8000 -> 0x8000_aaaa
0x0000_4000 -> 0x4000_aaaa
0x0000_2000 -> 0x2000_aaaa
0x0000_1000 -> 0x1000_aaaa
[...]
0x0000_0008 -> 0x0008_aaaa
0x0000_0004 -> 0x0004_aaaa
0x0000_0002 -> 0x0002_aaaa
0x0000_0001 -> 0x0001_aaaa水印是存在的,尽管我怀疑它是从以前的调试会话中得到的。我将在稍后讨论这个问题,因此,我目前的主要关注点是传递“will”-test。
下面是一个内存转储:
(gdb) x/16b addr
0x80000000: 0x00 0x00 0x55 0x55 0x55 0x55 0x00 0x80
0x80000008: 0xaa 0xaa 0xaa 0xaa 0xaa 0xaa 0x00 0x55
(gdb) p/x *addr
$59 = 0x55550000
(gdb) set *addr = 0xaabbccdd
(gdb) p/x *addr
$60 = 0xccdd0000
(gdb) x/16b addr
0x80000000: 0x00 0x00 0xdd 0xcc 0xbb 0xaa 0x00 0x80
0x80000008: 0xaa 0xaa 0xaa 0xaa 0xaa 0xaa 0x00 0x55有人能告诉我这种行为的原因吗?
干杯
注意:我故意遗漏了MCU和DRAM规范,因为我认为这个问题只能用JEDEC/DFI来解决。
编辑:添加了内存转储。
编辑:这里的是“步行位”-test的来源。在DRAM上的内存区域,从MCU内部运行。假定无漏洞:
static u32 __memtest_databus(volatile u32 * const addr)
{
/* Walking bit */
u32 pattern = (1u << 31);
u32 failmask = 0;
for(; pattern; pattern >>= 1)
{
*addr = pattern;
if(*addr != pattern)
failmask |= pattern;
}
return failmask;
}编辑:已检查PLL和VCO,并且设置是正确的。锁相环是稳定的,DRAM PHY确实获得了一个锁。
链接到DRAM数据表
发布于 2016-05-10 12:12:19
字节看起来像是移动了,而不是改变了。
报价
(gdb) x/16b addr
0x80000000: 0x00 0x00 *0xdd 0xcc 0xbb 0xaa* 0x00 0x80
0x80000008: 0xaa 0xaa 0xaa 0xaa 0xaa 0xaa 0x00 0x55取消报价
发布于 2016-05-10 13:42:23
这里有一个严重的bug:u32 pattern = (1 << 31);。
整数常量1是int类型的,它是ARM系统上的32位。
您将这个有符号的数字移出边界,调用未定义的行为;任何事情都可能发生。变量pattern可以得到任何值。
正确的代码将是u32 pattern = (u32)1 << 31;或u32 pattern = 1u << 31;
https://stackoverflow.com/questions/37131447
复制相似问题