痞子衡嵌入式:在i.MXRT1060-EVK上利用memtester程序给SDRAM做压力测试
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是在i.MXRT1060-EVK上利用memtester程序给SDRAM做压力测试。
我们知道恩智浦i.MXRT1xxx系列是高性能MCU的代表,对于这个超高主频(>=500MHz)的怪兽,不做点人机交互图形显示或者跑点算法方面的高阶应用实在有点浪费它的能力,高阶应用往往需要大容量缓存(RAM),i.MXRT1xxx系列内部RAM最大也就1-2MB,不是特别宽裕,因此我们在板级设计时往往会为i.MXRT1xxx再搭配一块外部RAM。外部RAM的种类选择很多,可通过FlexSPI外设挂HyperRAM/PSRAM或者通过SEMC外设挂SDRAM/SRAM,其中SDRAM是最常见的选择,官方EVK上默认也是选了SDRAM。
有了外部SDRAM虽然解决了系统缓存容量危机,但也同时可能引入潜在的系统稳定性问题,毕竟SDRAM是外部器件,容易受干扰(比如PCB走线或者环境温度等),如果SDRAM的读写访问不可靠,那么系统就会有不可预知的奇怪问题发生,因此我们需要在板子出厂时对SDRAM做一次压力测试(既测试了SDRAM芯片和PCB设计,也测试了对应的SEMC外设配置),今天痞子衡就选用memtester程序给SDRAM上一次强度。
关于memtester程序的基本知识,痞子衡之前专门写过一篇文章 《内存读写正确性压力测试程序(memtester)》 ,本篇就是基于了解memtester基本知识之后的一次实践。来,让我们开始吧。
一、准备工作
1.1 硬件平台NXP i.MX RT1060 EVK
要开始给SDRAM做压力测试,首先你得有一块开发板,恩智浦官网上有i.MXRT1060评估板,板载SDRAM芯片型号为镁光的MT48LC16M16A2,我们今天就来测试它。
1.2 集成开发环境IAR EWARM
ARM Cortex-M微控制器的集成开发环境有很多,其中IAR EWARM凭借优良的特性备受广大工程师青睐,今天痞子衡就选用IAR作为软件环境,具体版本为IAR EWARM v8.50.6。
1.3 官方软件开发包NXP MCUXpresso SDK
在开始移植memtester程序到i.MXRT1062上之前,我们需要先有一个i.MXRT1062的基本hello world的例程,当然我们可以对着数据手册自己从头写一个,但是这里痞子衡推荐使用官方软件开发包。
注册并登录恩智浦官网,来到 MCUXpresso SDK Builder 页面,在"Select Development Board"里选择EVK-MIMXRT1060后点击Build MCUXpresso SDK后跳转到下一个页面,点击Download SDK后便可得到SDK_2.9.1_EVK-MIMXRT1060.zip,下面是痞子衡下载的开发包具体版本信息:
二、开始实测
2.1 跑通hello world
给i.MXRT1060 EVK板子供电(J2口接5V输出的电源),并且使用USB线连接电脑与板子的J41 USB口,此时在设备管理器应该可以看到USB虚拟的串口(EVK板载LPC-LINK2调试器内含USB转串口功能,如果看不到串口,请自行安装LPC-LINK2驱动)。
打开前一步下载的开发包里的\SDK_2.9.1_EVK-MIMXRT1060\boards\evkimxrt1060\demo_apps\hello_world\iar\hello_world.eww工程,确认工程option里linker文件选择的是MIMXRT1062xxxxx_ram.icf,然后J21 JTAG口连接上Jlink Plus直接将工程下载进主芯片的RAM运行。
如果工程运行正常,你在串口调试助手(115200,8N1)里应该能看到"hello world."打印输出。
2.2 移植memtester程序
以hello_world工程为基础,将从官方网站下载到的memtester-4.5.0.tar包解压,将\memtester-4.5.0\路径下的如下源文件(.c或.h)全部拷贝到hello world工程目录下:
\memtester-4.5.0
\memtester.h
\memtester.c --主程序入口
\sizes.h --关于系统位数(32/64bit)的一些定义
\types.h --所用数据类型的定义
\tests.h
\tests.c --测试算法子程序
将上面所有memtester源文件全部添加进hello_world工程并将工程更名为memtester,然后再将工程中原主函数入口文件hello_world.c更名为main.c,此时基本memtester工程就完成了。但注意此时工程无法编译,因为memtester源文件还需要进一步修改。
2.2.1 适配嵌入式平台
我们下载的memtester源码本用作在Unix-like系统上运行的,所以源码里面有一些仅适用于Unix-like系统上运行的代码,需要将这些代码全部删除以适合在嵌入式平台运行。
关于头文件引用部分,需要删除memtester.c和tests.c文件里的一些不适用的#include语句,改用SDK里的标准头:
// 下述Unix系统头需删除
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
// 下述SDK标准头需添加
#include "fsl_common.h"
#include "fsl_debug_console.h"
整个memtester源码其实最主要(唯一)的改动就是memtester.c里的原main()函数,本来main函数是接受控制台传来的用户选项完成解析获取必要的参数(内存起始地址,测试长度,压力测试循环次数),然后运行tests.c里各种算法子程序。我们需要做的就是将main函数里代码各种删减,把不适用于MCU上运行的代码全部拿掉,并且将main函数原型改为如下:
/*******************************************************************************
* Input parameters:
* ---- phystestbase : memory base address
* ---- wantraw : memory size
* ---- memsuffix : memory unit, B,K,M,G for B, KB, MB, GB
* ---- loop : memory test code loop times
* ---- pagesize : memory pase size (Bytes)
*/
int memtester_main(ul phystestbase, ul wantraw, char *memsuffix, ul loops, ul pagesize)
{}
最后memtester_main里跑tests.c里具体算法子程序时,如果遇到失败的情况,默认是继续执行下一个算法子程序,我们可以加一个fail_stop控制变量,决定遇到失败是直接结束整个测试还是继续往下跑。
2.2.2 板级初始化
上一节里已经将memtester.c里面的main()函数改成了memtester_main(),所以我们直接在原hello_world.c改成的main.c里的main函数中增加memtester_main()的调用即可,注意按需设置测试参数(下述代码里的设置就是一个示例,测试0x8000_0000地址开始的64KB内存,循环一次即可)。此外Cache是否使能对测试影响很大,建议关掉DCache测试。
typedef struct _semc_test_config {
uint32_t baseAddr;
uint32_t testSize;
uint32_t loopNum;
uint32_t dramFreq;
uint32_t enableCache;
} semc_test_config_t;
int fail_stop = 1;
int main(void)
{
char memsuffix = 'B';
/* Init board hardware. */
BOARD_InitHardware();
/* --------------- stress test --------------- */
semc_test_config_t testConfig;
testConfig.baseAddr = 0x80000000;
testConfig.testSize = 64 * 1024;
testConfig.loopNum = 1;
testConfig.dramFreq = CLOCK_GetFreq(kCLOCK_SemcClk);
testConfig.enableCache = 0;
if (!testConfig.enableCache) {
/* Disable D cache */
SCB_DisableDCache();
}
PRINTF("\r\n########## Print out from target board ##########\r\n");
PRINTF("\r\nSDRAM r/w test settings:\r\n");
PRINTF(" Base Addr: 0x%x;\r\n", testConfig.baseAddr);
PRINTF(" Test Size: %d Bytes;\r\n", testConfig.testSize);
PRINTF(" Test Loop: %d;\r\n", testConfig.loopNum);
PRINTF(" SDRAM Freq: %d Hz;\r\n",testConfig.dramFreq);
PRINTF(" Enable Cache: %d;\r\n\r\n", testConfig.enableCache);
/* Run memory stress test: 64KByte, loop=1, page_size = 1kbyte */
memtester_main(testConfig.baseAddr, testConfig.testSize, &memsuffix, testConfig.loopNum, (1*1024));
while (1)
{
}
}
2.2.3 串口打印功能
串口打印功能的改动比较简单,直接把原memtester.c和tests.c文件里的fprintf()全部替换成PRINTF()即可,PRINTF函数在原hello world工程里已经实现了。
2.3 memtester参数配置
痞子衡在memtester程序的基本知识介绍里说过,memtester几乎没有参数配置,就是需要在sizes.h文件里把如下两个宏加进去:
#define ULONG_MAX (4294967295UL)
#define TEST_NARROW_WRITES
2.4 输出memtester结果
到这里memtester的移植工作就完全结束了,此时memtester工程(代码和变量都链接在TCM里)也应该能正常编译了。你可能会疑问,SEMC外设的初始化代码在哪里啊?别急,工程选项调试器设置里提供了两种SDRAM初始化脚本,我们随便选用一种即可:
另外需要注意的是,在工程预编译选项里需要加上SKIP_SYSCLK_INIT宏,因为工程时钟初始化函数BOARD_BootClockRUN()会根据这个宏来决定要不要重配SEMC,我们已经有SDRAM初始化脚本了,不需要在工程里再配SEMC时钟了。
现在还等什么?将memtester工程赶紧下载进芯片并打开串口调试助手看memtester结果啊。痞子衡为了尽快得到结果,仅测试了64KB的空间,按说应该测试全部32MB空间才对,但这个测试时间是很漫长的,如果循环次数loopNum大于1,那等待时间就更长了。如果测试中遇到了失败,除了要检查板级硬件外,还可以调整SDRAM初始化脚本里的配置再次测试,直至通过压力测试。
想偷懒的朋友直接移步痞子衡的github https://github.com/JayHeng/cortex-m-apps 去下载移植好的工程,工程在\cortex-m-apps\apps\memtester_imxrt1062\bsp\下面。
至此,在i.MXRT1060-EVK上利用memtester程序给SDRAM做压力测试痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。
痞子衡嵌入式:在i.MXRT1060-EVK上利用memtester程序给SDRAM做压力测试的更多相关文章
- 痞子衡嵌入式:揭秘i.MXRT1170上串行NOR Flash双程序可交替启动设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1170上串行NOR Flash双程序可交替启动设计. 在上一篇文章 <i.MXRT1060/1010上串行NOR F ...
- 痞子衡嵌入式:解锁i.MXRTxxx上FlexSPI模块自带的地址重映射(Remap)功能
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT三位数系列隐藏的FlexSPI Remap功能. 前段时间痞子衡写了一篇文章 <利用i.MXRT1060,1010上新 ...
- 痞子衡嵌入式:聊聊i.MXRT1xxx上的普通GPIO与高速GPIO差异及其用法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT上的普通GPIO与高速GPIO差异. GPIO 可以说是 MCU 上最简单最常用的外设模块了,当一些原生功能外设接口模块不能 ...
- 痞子衡嵌入式:实测i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1010上的普通GPIO与高速GPIO极限翻转频率. 上一篇文章 <聊聊i.MXRT1xxx上的普通GPIO与高速GP ...
- 痞子衡嵌入式:在i.MXRT1170上启动含DQS的Octal Flash可不严格设Dummy Cycle (以MT35XU512为例)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是Octal或Hyper Flash上DQS信号与Dummy Cycle联系. 关于在 i.MXRT 上启动 NOR Flash 时如何设 ...
- 痞子衡嵌入式:揭秘i.MXRT1170上用J-Link连接复位后PC总是停在0x223104的原因
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1170上安全调试策略实现对JLink调试的影响. 痞子衡之前写过一篇旧文 <i.MXRT600的ISP模式下用J-L ...
- 痞子衡嵌入式:利用i.MXRT1060,1010上新增的FlexSPI地址重映射(Remap)功能可安全OTA
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT部分型号上新增的FlexSPI Remap功能. OTA升级设计几乎是每个量产客户都绕不开的话题,产品发布后免不了要做固件( ...
- 痞子衡嵌入式:再测i.MXRT1060,1170上的普通GPIO与高速GPIO极限翻转频率
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1060/1170上的普通GPIO与高速GPIO极限翻转频率. 按照上一篇文章 <实测i.MXRT1010上的普通GP ...
- 痞子衡嵌入式:揭秘i.MXRT1060,1010上串行NOR Flash冗余程序启动设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1060,1010上串行NOR Flash冗余程序启动设计. 工业产品设计里经常会有冗余程序/备份程序设计的需求,因为在工业 ...
- 痞子衡嵌入式:记录i.MXRT1060驱动LCD屏显示横向渐变色有亮点问题解决全过程(提问篇)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1060上LCD横向渐变色显示出亮点问题的分析解决经验. 痞子衡前段时间在支持一个i.MXRT1060客户项目时遇到了LCD ...
随机推荐
- 完整的javaweb文档
1.index.jsp <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8&qu ...
- kali Linux--打开&关闭防火墙
1.安装ufw apt-get install ufw 2.关闭防火墙 ufw disable. 3.开启防火墙 ufw enable
- STM32F103 的 USART5使用
STM32F103zet6 的串口5是UART5 不是 USART5
- noi 1.1 5 输出保留12位小数的浮点数
描述 读入一个双精度浮点数,保留12位小数,输出这个浮点数. 输入 只有一行,一个双精度浮点数. 输出 也只有一行,保留12位小数的浮点数. 样例输入 3.1415926535798932 样例输出 ...
- python机器学习——线性回归方法
背景与原理: 线性回归是机器学习建模中最为简单的模型,也是计算起来最为直观的模型 所谓线性回归,我们要建立的是这样的模型:对一组数据,每组数据形如$(x_{1},...,x_{n},y)$,我们希望构 ...
- Epoll的使用例子
本篇文章在上一篇的基础上,使用 epoll 实现了一个事件监听和回调处理的模块.如何编写一个使用该模块的例子呢? 监测什么类型的fd,监测什么类型的事件,监测到事件以后需要做什么?后来可以看看如何将 ...
- python3GUI--天气预报小工具By:PyQt5(附源码)
@ 目录 一.准备工作 二.预览 1.启动 2.添加城市 三.设计流程 1.UI设计(草图) 2.UI设计(QT设计师) 3.解释 四.源代码 五.总结 之前用tk写过一款python3GUI--天气 ...
- 07 HBase操作
1.理解HBase表模型及四维坐标:行键.列族.列限定符和时间戳. 2.启动HDFS,启动HBase,进入HBaseShell命令行. 3.列出HBase中所有的表信息list 4.创建表create ...
- 关于数据传递 json
关于这几种语言的json 操作 Lua local cjson2 = require "cjson" local lua_object = { ["name"] ...
- 关于VScode里TS文件内引入插件没有提示内置属性和方法这件事
前几天使用VScode + Vue + Vite + Ts开发项目 由于自己手残 把VScode设置文件的代码做了一些修改 导致TS文件引入的插件没有提示了!! 几经折腾下 终于靠自己解决了! 不多说 ...