keil程序在外部RAM中调试的问题总结

keil程序在内部RAM调试的基本步骤网上已经有很多了,我就不再赘述,大家可以在网上搜到很多。


但是有些时候内部RAM并不够用,这就需要将程序装入外部RAM中调试,而在这个过程中可能会出现各种各样的问题,在这里我将会把我遇到过的一些问题和需要注意的地方总结一下,希望能够对大家有所帮助。


有错误的地方也希望大神们能够不吝赐教,提前表示感谢···


转载请注明出处:waitig's blog


先介绍下我项目使用的硬件,芯片是LPC1788,外部RAM是MT48LC4M32B2,大小为16M(128Mb X32 SDRAM),之前用的是MT48LC2M32B2,大小为8M,后来发现东西太多,8M不够用了,所以换成了16M的。

在换RAM时也遇到过一些问题,这个在下文中会有介绍。


  • 在外部RAM中调试程序,程序中一定不能有操作外部RAM的代码!


在外部RAM中调试,程序中不要有操作外部RAM的代码,初始化也不要有,包括对RAM相关引脚的操作。

RAM的初始化和引脚的初始化要放到jlink的下载配置文件中,主要是对LPC的寄存器进行相关配置,不要忘了RAM中的读取算法配置。

把我的配置文件贴出来供大家参考一下。

FUNC void PinSel(int p1, int n1, int f1)
{
    _WDWORD(0x4002C000 + (p1 * 32 + n1) * 4, 0x8 | f1);
}

FUNC void InitSDRAM(void)
{
    int i;
    
    PinSel(2,16,1);
    PinSel(2,17,1);
    PinSel(2,18,1);
    PinSel(2,20,1);
    PinSel(2,24,1);
    PinSel(2,28,1);
    PinSel(2,29,1);
    PinSel(2,30,1);
    PinSel(2,31,1);

    for(i = 0; i < 32; i++)
        PinSel(3,i,1);
        
    for(i = 0; i < 21; i++)
        PinSel(4,i,1);

    PinSel(4,24,1);
    PinSel(4,25,1);
    PinSel(4,30,1);
    PinSel(4,31,1);
    
    /* PCONP |= 1 << 11 */
    _WDWORD(0x400FC0C4, 0x04288FDE);    // Power On EMC

    /* EMCCONTROL |= 1 */
    _WDWORD(0x2009C000, 0x00000001);    // Enable EMC

    /* EMCDLYCTL */
    _WDWORD(0x400FC1DC, 0x00081818);    // Config data read delay

    /* EMCCONFIG */
    _WDWORD(0x2009C008, 0x00000000);    // Little endian mode

    /* DYNAMICCONTROL */
    _WDWORD(0x2009C020, 0x00000003);    // Set normal self refresh mode, normal power mode
                                        // CE always HI
                                        // Enable clock out
                                        // Clock do not stop during idle

    /* DYNAMICREFRESH */
    _WDWORD(0x2009C024, 0x0000001F);    // refresh timing 

    /* DYNAMICREADCONFIG */
    _WDWORD(0x2009C028, 0x00000001);    // read timing 

    /* DYNAMICRP */
    _WDWORD(0x2009C030, 0x00000002);    // tRP

    /* DYNAMICRAS */
    _WDWORD(0x2009C034, 0x00000003);    // tRAS
    
    /* DYNAMICSREX */
    _WDWORD(0x2009C038, 0x00000005);    // tSREX

    /* DYNAMICAPR */
    _WDWORD(0x2009C03C, 0x00000001);    // tAPR

    /* DYNAMICDAL */
    _WDWORD(0x2009C040, 0x00000005);    // tDAL

    /* DYNAMICWR */
    _WDWORD(0x2009C044, 0x00000003);    // tWR

    /* DYNAMICRC */
    _WDWORD(0x2009C048, 0x00000004);    // tRC

    /* DYNAMICRFC */
    _WDWORD(0x2009C04C, 0x00000004);    // tRFC

    /* DYNAMICXSR */
    _WDWORD(0x2009C050, 0x00000005);    // tXSR

    /* DYNAMICRRD */
    _WDWORD(0x2009C054, 0x00000001);    // tRRD

    /* DYNAMICMRD */
    _WDWORD(0x2009C058, 0x00000003);    // tMRD

    /* DYNAMICCASRAS0 */
    _WDWORD(0x2009C104, 0x00000303);    // RAS/CAS Latency

    /* DYNAMICCONFIG0 */
    _WDWORD(0x2009C100, 0x00004500);    // Config device type as SDRAM
                                        // Config address mapping

    _sleep_(100);                       // Wait 100 ms

    /* DYNAMICCONTROL */
    _WDWORD(0x2009C020, 0x00000183);    // nop command

    _sleep_(100);                       // Wait 100 ms

    /* DYNAMICCONTROL */
    _WDWORD(0x2009C020, 0x00000103);    // pre-charge command
    
//    /* DYNAMICREFRESH */
//    _WDWORD(0x2009C024, 0x00000002);    // refresh timing 

    _sleep_(100);                       // Wait 100 ms

    /* DYNAMICREFRESH */
    _WDWORD(0x2009C024, 0x0000001F);    // refresh timing 
    
    /* DYNAMICCONTROL */
    _WDWORD(0x2009C020, 0x00000083);    // mode command
    _RDWORD(0xA0000000 | (0x32 << (2 + 2 + 8)));
    
    _sleep_(100);                       // Wait 100 ms

    /* DYNAMICCONTROL */
    _WDWORD(0x2009C020, 0x00000003);    // noamal command

    /* DYNAMICCONFIG0 */
    _WDWORD(0x2009C100, 0x00084500);    // enable buffer
    
    _sleep_(100);                       // Wait 100 ms
}

以上是外部RAM的初始化部分,不要忘了其中的RAM本身的寄存器,在本例中的地址是0xA0000000,寄存器中的各个位数的作用如下图:


(截图自MT48LC4M32B2的datasheet)

其中数据要配置正确,RAM才能正确工作。接下来是对内存保护单元(MPU)的配置,两者结合,就是Jlink对RAM的初始化和配置。


RAM_Debug.ini 的文件如下所示:

INCLUDE MT48LC4M32LFB5.ini

InitSDRAM();                                // Initialize memory

LOAD ..\SDRAM_obj\uc1788.axf INCREMENTAL    // Download program

/* RNR */
_WDWORD(0xE000ED98, 0x00000000);            // Use No.0 MPU

/* RBAR */
_WDWORD(0xE000ED9C, 0xA0000000);            // Set MPU base addr

/* RASR */
_WDWORD(0xE000EDA0, 0x03000031);            // Set MPU size and permission

/* SHCSR */
// _WDWORD(0xE000ED24, 0x00000100);            // Enable memory managemeng fault

/* MPU_CONTROL */
_WDWORD(0xE000ED94, 0x00000005);            // Enable MPU

/* VTOR */
_WDWORD(0xE000ED08, 0x10000000);            // Set vector table offset

SP = _RDWORD(0x10000000);                   // Set stack pointer
PC = _RDWORD(0x10000004);                   // Set program counter

这样就能像在FLASH中调试一样来在RAM中调试了。

但是,程序中不要出现任何操作RAM的代码!一定记住!


  • 程序装入RAM中起始地址出错


所谓起始地址,就是指程序刚装入RAM中,还没有运行的那个pc地址。

正常情况下,这个地址是指向芯片启动代码的systemiInit()这个函数所在的地址的,但是有些时候这个地址会出错,跑到一个不知道什么地址的地方去。


如下图所示:



我分析出现这个现象的原因是在jlink对RAM的配置方面有问题,也就是对RAM没有配置成功,导致程序没有成功存入RAM中,或者是储存成功,但是读取失败,或者储存读取都有问题。


解决方案就是查看内存中的数据,看是否正确。或者对设备重新上电,对jlink复位后重新调试。


这个问题在我这里偶尔会出现,但重新调试又会消失,所以到目前我也没弄清楚这个问题出现的原因。


  • 程序跑入HardFault_Handler

HardFault_Handler是指指令错误中断,一般是因为程序代码翻译成的汇编代码中出现了错误的指令。

解决这个问题的方法一般是找出错误指令的地址,如果地址是在当前分配的代码段的最开始位置(比如我在分散加载里面将这段代码放在0xA0001000-0XA0002000之间,然后出错指令出现在0xA0001010这个位置);

或者在上个代码段的结束位置(比如我将这段代码放在0xA0001000位置处,上段代码在0xA0000900结束,而出错指令在0xA0000920这个位置);

一般情况下是内存不够用导致的,而且出错的语句一般是向全局变量赋值的语句。因为内存不够用,但是jlink在向RAM中写数据的时候并不知道内存不够,导致后来溢出的数据折返回代码段起始地址,将以前的内容覆盖所导致的。(内存覆盖)


解决这个问题的方法就是换一个大的RAM。


还有一种可能,就是在程序中有操作RAM的代码,这也会导致RAM中内容被修改,出现错误的指令。


  • 程序中途跑飞


上一条中的问题也有可能导致程序中途跑飞,此外还有一种可能就是指针问题。

指针没有正确初始化,使用了未初始化的指针,或者是指针没有正确回收,导致出现野指针,是最常见的,也是最容易导致程序跑飞的原因。出现问题应最先考虑此因素。


排除了以上的因素后,可以根据那些常规方法,比如查看LR寄存器的值,找到出现问题的语句等方法来查找具体原因。


  • 更换新外部RAM时要注意的问题


更换新RAM之前先看RAM的手册和芯片的手册,看清楚使用的芯片支持不支持新的RAM,我就因为没看清楚手册导致买了芯片不支持的RAM,既费钱又费力。。。。

芯片user manul上一般都有一个表,表中就是它所支持的所有RAM的类型。如下图:



先查清楚再买芯片,血淋淋的教训。。。


不同的RAM读写规则有些会有所不同,配置也不尽相同,所以在更换新RAM时要仔细读懂RAM的datasheet,对其清楚掌握。

基本上需要配置的最主要参数有以下几个:页大小,外部总线地址映射(行,列,bank),空间大小,位数,读写的算法(在RAM自己的寄存器中配置);

外部总线地址映射要与芯片对应,然后通过上表来确定配置寄存器的值。(程序在RAM中调试要修改jlink的ini文件)



  • 结语:暂时就想到了这些,以上的问题都是我在实际项目中碰到的问题,和一些经验介绍。由于我自己也学艺不精,能力有限,所以难免有错误的地方,希望路过的大神可以帮忙指正。同时声明,仅供参考。


转载请注明出处:waitig's blog


文章标签:  经验 工作 硬件 嵌入式 lpc1788
个人分类:  C语言 LPC1788 嵌入式之路
相关热词:  keil的介绍  keil驱动安装  keil另存为  keil导包  keil秘钥
上一篇STM32F103频率和AD采集项目总结
下一篇keil将程序装入外部FLASH详解
keil程序在外部RAM中调试的问题总结_第1张图片

RAM调试STM32程序的配置方法

Design by:Liunus [email protected] qq:894693627 20140103 在RAM中调试STM32 早就听说可以在RAM中调试STM32程序了,直到昨天晚上...

liuu67xin liuu67xin

2014-01-03 21:30:12

阅读数:4167

STM32内部RAM在线调试配置方法及详细说明(基于Keil开发工具)

Ⅰ、写在前面本文主要讲述的内容:基于Keil开发工具下,STM32内部RAM在线调试配置方法,以及每一项配置的详细说明。如需要了解更多相关的文章,可以到我博客,或微信公众号查看。 让程序运行在RAM中...

ybhuangfugui ybhuangfugui

2016-09-22 23:37:12

阅读数:9583

区块链以太坊DApp高薪实战,报名即可领取助学金八月精通区块链开发,月薪四万很轻松,渐进式构建从原理到实战的知识体系,以太坊DApp项目从0到1实战演示。

MDK linker和debug的设置以及在RAM调试

有误或者表述不清楚请指出,谢谢  硬件:TQ2440开发板、jlink  V8 固件 软件:J-LINK  ARM 4.08i、MDK4.20 先解释下MDK中三种link...

rockrockwu rockrockwu

2011-12-21 20:33:36

阅读数:11562

keil调试查看ROM或RAM

Ctrl+F5或点击调试按钮进入调试界面:   在工具栏上点击Memory Windows 则右下角出现Memory1的页面,默认出现的是ROM的查看界面,在Address一栏输入十六进制的地址即...

chenhezhuyan chenhezhuyan

2013-03-29 11:27:51

阅读数:8809

keil工程选项设置

首先点击左边 Project 窗口的 Target 1,然后使用菜单“Project->Option for target ‘target1’”即出现对工程设置的对话框,这个对话框可谓非常复杂,共有 ...

luckywang1103 luckywang1103

2013-09-29 21:21:27

阅读数:12545

51单片机同时外扩RAM,ROM的具体实现及Keil的具体设置

http://www.51hei.com/bbs/dpj-29346-1.html 51MCU内部有RAM,ROM,不同于8031。尽管如今的增强行51MCU的内部RAM,ROM可能已经很大的空...

chungle2011 chungle2011

2015-01-01 20:22:23

阅读数:2206

老中医说:男人多吃的话,时间长5倍!锐飞 · 顶新

keil MDK在RAM调试

参照《RealView MDK 下ARM 程序在RAM 中调试的方法》(杨广京 中科院自动化所)文章,实验在RAM中调试程序,以便设置多个断点和延长FLash寿命。步骤如下: 1、修改IROM1(0...

mcu_hong mcu_hong

2013-03-14 20:33:26

阅读数:3635

KEIL之ARM中常驻RAM程序设计方法

KEIL之ARM中常驻RAM的程序设计方法 转自:http://wenku.baidu.com/link?url=0OaySZQVDOTnCYEstVC-m4z5vzpWI5Uyxsb1ae...

xlhcgd xlhcgd

2015-06-24 14:29:35

阅读数:405

ARM如何指定函数运行在RAM--KEIL

两种方法,假设要要运行在RAM的函数统一放在download.c文件中   第一种方法:(采用默认的sct分散文件) 将要运行在RAM的函数放在一个文件中。在KEIL右键点击该文件"...

Ropai Ropai

2013-05-20 14:56:48

阅读数:3672

从0开始学Keil下的S3C2440裸机开发-3使用外部NORFLASH+内部RAM

关于S3C2440启动方式: 程序下载到NORFLASH中后,选择从NORFLASH启动,自动执行,NORFLASH中执行代码,内部RAM分配变量;NORFLASH本身地址映射为0X000000...

xiaoaide01 xiaoaide01

2014-07-21 15:57:04

阅读数:760

程序外部RAM运行的例子 -ARM

2010年01月17日 43KB 下载

Keil的片外RAM区支持设置

转自http://blog.mcuol.com/User/jaywei518/Article/57014_1.htm 还没看会  先转过来收藏一下 最近对ucosii很感兴趣,主要是看li...

gmdjmawy gmdjmawy

2015-08-08 16:31:29

阅读数:2602

nRF52832 — Keil中如何配置RAM地址

写在前面:在使用Keil过程中,有时需要自己手动配置RAM地址,那么如何根据SoftDevice的大小计算呢? 1、烧录报错: 当更改了芯片型号或者新建工程时,烧录会提示:Error: F...

zhanghuaishu0 zhanghuaishu0

2018-01-11 20:47:18

阅读数:732

STM32学习之:RAM的分配和占用

一个小的项目,在测试时间和产品量稍微大一些之后,出现了一些莫名其妙的非逻辑错误的Bug(最头疼的是不能每次都能复制出来)。经过修改后,最近一个月的测试都没有出现。本人在这里得到了原子哥和其他朋友的很多...

Cheatscat Cheatscat

2018-05-04 14:39:28

阅读数:278

Keil MDK使用J-LINK分别在Sram,Nor Flash以及Sdram调试代码的原理和方法

一、概述 MDK开发ARM裸机程序时,在调试阶段通常是先让程序在SDRAM中执行,以加快调试速度,也避免频繁烧写Nor Flash,因此需要知道如何指定程序在哪个位置执行。本文以realarm 241...

KenZhang1031 KenZhang1031

2016-05-09 23:31:42

阅读数:2235

Keil MDK从未有过的详细使用讲解

转自:http://blog.csdn.net/yx_l128125/article/details/9144887 转自博客:http://blog.csdn.net/zhzht1986101...

u012252959 u012252959

2016-03-26 15:10:00

阅读数:1131

KEIL调试错误总结

2011年08月24日 42KB 下载

LPC1788在外部RAM调试总结

一、MDK设置 1、Target                   图1 2.Asm                  图2   1处必须预定义NO_CRP,因为在LPC1788启动...

lgd370323 lgd370323

2015-09-19 21:21:47

阅读数:2269

emWin使用外部SRAM的方法

emWin使用外部SRAM的方法 标签: emWinSRAM内存STM32 2013-07-12 16:51 3422人阅读 评论(3) 收藏 举报  分类: uCGU...

u011558786 u011558786

2017-10-24 11:30:30

阅读数:304

关于EMWIN移植、enwin调试时候卡GUI_Init的问题

最近在调试移植emwin到STM32时候出现了一些问题,百度后发现之前有不少人也出现了相应的问题,但都没有 看到有用的解决方法出来。希望我这个文章能帮到一些朋友。  根据emwin使用指南开始...

qq_41633543 qq_41633543

2018-01-31 14:47:25

阅读数:658

个人资料

关注
原创
84
粉丝
26
喜欢
5
评论
21
等级:
访问:
19万+
积分:
2510
排名:
1万+
勋章:

最新文章

  • WSingle站群系统,全网唯一支持【站群】的WordPress小说主题!
  • WSingle主题 – 支持多本的WordPress小说主题,美观大方,功能强大
  • WSingle主题 – 可能是最好的WordPress小说主题,美观大方,功能强大
  • WordPress多本小说主题–WNovel主题,现已更新至1.2版本
  • InfluxDB系列学习教程目录

个人分类

  • CMD4篇
  • java11篇
  • android1篇
  • php6篇
  • Ubuntu15篇
  • VIM配置5篇
  • css1篇
  • C语言8篇
  • 课程设计11篇
  • 测试3篇
  • MFC3篇
  • STM32学习4篇
  • 嵌入式之路5篇
  • LPC17884篇
  • keil3篇
  • 解决方案12篇
  • 反馈1篇
  • 服务器搭建4篇
  • 无关技术1篇
  • Github与Git1篇
  • wordpress11篇
  • Linux22篇
  • 经验总结3篇
  • WordPress主题5篇
  • 等英软件1篇
  • Shell10篇
  • InfluxDB4篇
  • 编程语言1篇
  • Wordpress小说主题3篇

展开

归档

  • 2017年11月1篇
  • 2017年10月2篇
  • 2017年8月1篇
  • 2017年7月3篇
  • 2017年3月2篇
  • 2016年9月8篇
  • 2016年7月1篇
  • 2016年6月1篇
  • 2016年5月8篇
  • 2015年9月3篇
  • 2015年8月10篇
  • 2015年6月5篇
  • 2014年9月5篇
  • 2014年8月4篇
  • 2014年6月3篇
  • 2014年4月3篇
  • 2014年2月1篇
  • 2013年12月2篇
  • 2013年11月1篇
  • 2013年10月11篇
  • 2013年9月1篇
  • 2013年8月12篇

展开

热门文章

  • 安卓真机测试:Installation error: INSTALL_CANCELED_BY_USER

    阅读量:31914

  • 【Tumload】-tumblr视频下载神器发布啦

    阅读量:17527

  • Linux Shell系列教程之(十一)Shell while循环

    阅读量:9220

  • WordPress媒体库图片不显示或显示错误的原因及解决方案

    阅读量:8031

  • VIM高亮显示当前行只显示下划线的问题解决方案

    阅读量:6614

最新评论

  • MFC执行CMD命令并获得其返回信...

    woshilds:为啥执行telnet 命令框会一闪而过呢

  • WordPress媒体库图片不显示...

    ufogycsdn:非常感谢,<!DOCTYPE> 声明必须是 HTML 文档的第一行,这...

  • C语言outtextxy函数输出整...

    VarryTan:那输出变量呢,你这仅仅只是输出固定值

  • C语言编写时钟程序

    x734926672:你好!我是一名刚学习VC6.0的新手小白,想问下您为啥这段代码在VC6.0运行时会出现C1.EVE...

  • httpd: unrecogniz...

你可能感兴趣的:(LPC54608,经验,工作,硬件,嵌入式,lpc1788,C语言,LPC1788,嵌入式之路,keil的介绍,keil驱动安装,keil另存为,keil导包,keil秘钥)