首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当遇到奇怪的问题时,用32位单片机锁定16位宽DRAM

当遇到奇怪的问题时,用32位单片机锁定16位宽DRAM
EN

Stack Overflow用户
提问于 2016-05-10 07:02:49
回答 2查看 107关注 0票数 2

我正在自定义板上工作,包括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"):

代码语言:javascript
复制
   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。

下面是一个内存转储:

代码语言:javascript
复制
(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内部运行。假定无漏洞:

代码语言:javascript
复制
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数据表

EN

回答 2

Stack Overflow用户

发布于 2016-05-10 12:12:19

字节看起来像是移动了,而不是改变了。

报价

代码语言:javascript
复制
(gdb) x/16b addr
0x80000000:     0x00    0x00    *0xdd    0xcc    0xbb    0xaa*    0x00    0x80
0x80000008:     0xaa    0xaa    0xaa    0xaa    0xaa    0xaa    0x00    0x55

取消报价

票数 0
EN

Stack Overflow用户

发布于 2016-05-10 13:42:23

这里有一个严重的bug:u32 pattern = (1 << 31);

整数常量1int类型的,它是ARM系统上的32位。

您将这个有符号的数字移出边界,调用未定义的行为;任何事情都可能发生。变量pattern可以得到任何值。

正确的代码将是u32 pattern = (u32)1 << 31;u32 pattern = 1u << 31;

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37131447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档