MicroZed测评7-测试更多的DDR内存空间

MicroZed上有256M*32bit的DDR3 RAM,换算为PC上的计算方法即1GB。上面我们已经运行了一个内存测试的程序,它是基于SDK中的模版生成的,如图1所示,其中分别包含了8位、16位和32位长度的内存测试。这些信息在运行MemTest程序的时候,会通过USB-UART发送到PC并显示在SDK的控制台中。

图1 MemTest测试的内存地址

图1 MemTest测试的内存地址

在MemTest的例子中,只测试了很小的一段4KB的内存地址。在SDK的工程管理器中,打开hw_platform_0下面的system.xml,我们可以看到ps7_ddr_0的地址范围是0x00100000到 0x3fffffff,即1072693248个字节、1023MB。那起始的低地址的1MB RAM空间被被用作片上空间(OCM)和保留空间,其初始配置如图2所示,具体的内容可以查询ug585的技术手册。

图2 RAM地址划分

图2 RAM地址划分

为了测试更多的RAM空间,我们可以修改测试程序。切换到SDK项目管理器中Mem_Test程序下面的src分类,然后打开memorytest.c文件。程序很短,很容易找到调用内存测试的那句:

for (i = 0; i test_memory_range(&memory_ranges[i]);
}

改变n_memory_ranges,就可以选择测试OCM和DDR3了。CPU0的OCM目前用来存放和运行我们的Mem_Test程序,所以不对其进行测试;在Mem_Test下面的lscript.ld内存链接文件中可以看到CPU0的内存地址分配情况。同样在memorytest.c中,test_memory_range的定义也很清晰地呈现在我们面前。为了方便定位程序,可以在SDK环境中,点击菜单栏上的Window---Perferences,找到并打开行号的设置,如图3所示。

图3 在SDK中显示行号

图3 在SDK中显示行号

在59、62和65行,有内存测试的函数:

status = Xil_TestMem32((u32*)range->base, 1024, 0xAAAA5555, XIL_TESTMEM_ALLMEMTESTS);
status = Xil_TestMem16((u16*)range->base, 2048, 0xAA55, XIL_TESTMEM_ALLMEMTESTS);
status = Xil_TestMem8((u8*)range->base, 4096, 0xA5, XIL_TESTMEM_ALLMEMTESTS);

可以看出,由模版生成的Mem_Test只进行了几次4KB长的内存测试。在这里我们就可以修改其中的地址长度了,例如1024、2048、4096。因为这个程序最初设计时,是既可以测试OCM,又可以测试DDR的,而由图3可以看出,OCM的地址范围要比DDR小的多,所以如果我们仅修改测试长度的话,显然会造成找不到对应的地址而出错。所以我们需要修改测试模式,只测试DDR空间,这样能够测试的地址范围就大的多。

打开Mem_Test程序下面的src分类中的memory_config.c,然后把n_memory_ranges从2改成1,然后注释掉掉ps7_ram_1的相关代码(选中多行代码,然后按键盘的Ctrl和/键就可以了),这样就能只测试DDR的空间了。

然后回到memorytest.c,改变59、62和65行中的待测试的内存长度,就可以测试更多的DDR空间了。如果希望测试全部的DDR3 RAM,就把地址范围改为最大值,即8bit测试的情况下最大范围是1072693248,16bit测试的情况下最大范围是1072693248/2=536346624,32bit测试的情况下最大范围是536346624/2=268173312;然后保存更改,SDK会自动编译程序,并把结果显示在SDK的控制台中,如图4所示。

图4 修改代码并编译程序

图4 修改代码并编译程序

从图4中可以看出,以十进制计算,生成的程序大小为48656字节,即47.5KB。而由图2中看出,在CPU模式下,CPU0的OCM有64*3=192KB,存放生成的Mem_Test.elf文件完全没有问题。

最后在SDK工程管理器中的Mem_Test项目下,点击右键选择Run As---Run Configurations,找到Xilinx C/C++ application (GDB)下面的Mem_Test Debug,并确认STDIO选项卡中已经正确配置UART之后,点击Run,就可以运行对CPU1中全部DDR3的测试了;全部的测试花费的时间将超过10分钟,其中32bit的测试最快,8bit的最慢。