Summary of problems with debugging the Keil program in external RAM (personal experience)

Source: Internet
Author: User
Tags jlink

The basic steps for debugging the Keil program in internal RAM are already available on the Internet, so I will not repeat them here. You can find a lot on the Internet.


However, sometimes the internal RAM is not enough, so you need to load the program into the external RAM for debugging. In this process, various problems may occur, here, I will summarize some of the problems I have encountered and the areas that need attention, hoping to help you.


In the case of any errors, I hope that you can give me some advice and express your gratitude in advance ···


Reprinted please indicate the source: waitig's blog


First, we will introduce the hardware used in our project. The chip is lpc1788, the external Ram is mt48lc4m32b2, And the size is 16 m (128 MB x32 SDRAM). Previously we used mt48lc2m32b2, And the size is 8 m, later I found that there were too many things and 8 m was not enough, so I switched to 16 m.

I also encountered some problems when changing Ram, which will be described below.


  • When debugging programs in external ram, the program must not have code to operate on external Ram!


In external Ram debugging, there should be no code for operating external RAM in the program or for initialization, including operations on Ram-related pins.

The ram initialization and pin initialization should be put into the jlink download configuration file, mainly to configure the LPC register, do not forget the read algorithm configuration in Ram.

Paste my configuration file for your reference.

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}

The above is the initialization part of the external Ram. Do not forget the ram register. In this example, the address is 0xa0000000. The functions of each single digit in the register are as follows:


(From Datasheet of mt48lc4m32b2)

The data must be correctly configured so that Ram can work correctly. The next step is the configuration of the memory Protection Unit (MPU). The combination of the two is the initialization and configuration of RAM by jlink.


The ram_debug.ini file is as follows:

INCLUDE MT48LC4M32LFB5.iniInitSDRAM();                                // Initialize memoryLOAD ..\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 offsetSP = _RDWORD(0x10000000);                   // Set stack pointerPC = _RDWORD(0x10000004);                   // Set program counter

In this way, you can debug in Ram like debugging in flash.

However, do not show any Ram operation code in the program! Remember!


  • An error occurred while loading the start address of the program into RAM.


The starting address is the PC address that the program has just loaded into RAM and is not running.
Under normal circumstances, this address points to the address of the systemiinit () function of the chip startup code, but sometimes this address will go wrong and go to a place where no address is known.


As shown in:



The reason for this problem is that jlink has a problem with ram configuration, that is, the ram is not configured successfully, and the program is not successfully saved to Ram or saved successfully, however, reading fails or storage reading is faulty.


The solution is to check the data in the memory to see if it is correct. Or power on the device again, reset the jlink, and then re-debug the device.


This problem occurs occasionally on me, but it disappears after debugging. So far, I have not figured out the cause of this problem.


  • The program runs into hardfault_handler.

Hardfault_handler refers to the command error interruption, generally because the program code is translated into an assembly code with an incorrect command.

The solution to this problem is generally to find out the address of the wrong command. if the address is at the beginning of the currently allocated code segment (for example, I placed the code in the distributed loading area between 0xa0001000-0xa0002000, then the error command appears at 0xa0001010 );

Or the end position of the previous code segment (for example, I put this code at 0xa0001000, the previous code ended at 0xa0000900, and the error command at 0xa0000920 );

Generally, this is caused by insufficient memory, and the wrong statement is generally a statement that assigns a value to the global variable. Because the memory is not enough, but jlink does not know that the memory is not enough when writing data to ram. As a result, the overflow data returns the starting address of the code segment and overwrites the previous content. (Memory coverage)


The solution to this problem is to change a large Ram.


Another possibility is that there is Ram code in the program, which may also cause the ram content to be modified and incorrect commands.


  • Programs run halfway


The problem in the previous article may also cause the program to run halfway, and another possibility is the pointer problem.

The pointer is not correctly initialized, the uninitialized pointer is used, or the pointer is not properly recycled, resulting in a wild pointer. This is the most common and most likely cause of program flight. This issue should be taken into consideration first.


After the above factors are excluded, you can find the specific cause based on the common methods, such as viewing the LR register value and finding the problematic statements.


  • Notes for changing external Ram


Before changing the new RAM, first read the ram manual and the chip manual. It is clear that the chip used does not support the new RAM. Because I did not see the manual clearly, I bought the Ram not supported by the chip, it is both costly and laborious ....

Generally, there is a table on the chip user manul, and the table is all the RAM types it supports. For example:



First, find out what it means to buy a chip...


Different Ram read/write rules may vary with different configurations. Therefore, you must carefully read the ram datasheet when replacing the new RAM.

The main parameters that need to be configured are page size, external BUS address ing (row, column, bank), space size, number of digits, read/write algorithms (configured in the ram register );

The external BUS address ing must correspond to the chip, and then the configuration register value is determined through the table above. (Program debugging in Ram to modify the INI file of jlink)



  • Conclusion: I have come up with these questions for the moment. The above questions are all problems I encountered in the actual project, and some experiences are introduced. Because I am not proficient in learning and have limited capabilities, it is inevitable that there will be errors. I hope the passing gods can help me correct them. The statement is for reference only.


Reprinted please indicate the source: waitig's blog


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.