This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How can (or should) one reference external SDRAM on Tiva TM4C129XNCZAD by modifying "SECTIONS" in .cmd file?

Other Parts Discussed in Thread: TM4C129XNCZAD, SYSBIOS

Configuration:
CCS Version: 6.1.0.00104    Compiler TIv5.1.7   TivaWare_C_Series-2.1.1.71    Bios_6_37_00_20
Hardware is other vendor  production board with Tiva TM4C129XNCZAD processor with 8 Mbyte external SDRAM on EPI bus.

I have 2 active projects which will require more ram than is available internally on the processor.
 I have not yet determined the correct/best method to build projects to "easily" reference the external SDRAM. I can only  reference the SDRAM as a big array using a pointer (not good enough) for my needs/desires.
I would like to assign a "SECTIONS" to SDRAM and use that where reasonable for SECTIONS like .data, .bss, .sysmem if that is possible.  
I just want to have more ram available for projects. I have not found a solution, if there is one, in the many, many references in the forums to external SDRAM,
only the way to reference SDRAM as a large array or structure.
I expect the external ram reference to be slower than internal memory and accept that limitation.

Present Situation:
Working code maps external SDRAM to 0x60000000.  Existing application runs without problems and provides access to SDRAM through use of a pointer defining the starting address of an array.  Present code accesses the SDRAM using writes and reads to store then read data at startup.  The SDRAM is also used as LCD display memory.  This works but limits C code to array reference.


I can easily overrun available heap when dynamically creating tasks, semaphores, mailboxes, etc.

Partial Progress:
Is it  correct to modify the *.cmd file produced by CCS in the project to add an SDRAM section of memory and to provide the address/size in this file.


My present code follows.  
 
With these changes to .cmd file, the project compiles and links without errors.  The .map file shows a SDRAM SECTION at the desired location.
The application fails at "startup" in "loader_exit" without getting to main() in application code.  
 
***  .cmd file modifications ****
MEMORY
{
    FLASH (RX) : origin = 0x00000000, length = 0x00100000
    SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    SDRAM (RW) : origin = 0x60000000, length = 0x00800000   (this line added)
}
/* Section allocation in memory */
 
SECTIONS
{
    .intvecs:   > 0x00000000
    .text   :   > FLASH
    .const  :   > FLASH
    .cinit  :   > FLASH
    .pinit  :   > FLASH
    .init_array : > FLASH
 
    .vtable :   > 0x20000000
    .data   :   > SRAM
    .bss    :   > SRAM
    .sysmem :   > SRAM
    .stack  :   > SRAM
 
    .sdram : > SDRAM    (this line added)
}


 *** .map snippet **

  FLASH                 00000000   00100000  0001f17e  000e0e82  R  X
  SRAM                  20000000   00040000  000293b0  00016c50  RW X
  SDRAM                 60000000   00800000  00000002  007ffffe  RW  


***********************  code snippet *******************************************************
// at module level - not within a procedure
#pragma DATA_SECTION(ExtData, ".sdram")
uint16_t ExtData;

// in a task procedure
 ExtData = 1;

********************************************************************************************

Above fails to reach main() as described above. Next try:


I am GUESSING that I need to insert a "startup" hook before BIOS_start() in main() to initialize the
EPI interface to the SDRAM, but am way out of my depth here.
My (bad) ideas for .cfg changes follow.  This does not even build.

***************** .cfg snippet   ******************************
var BIOS = xdc.useModule('ti.sysbios.BIOS');
BIOS.addUserStartupFunction('&SDRAMInit');          // this added
var Startup = xdc.useModule('xdc.runtime.Startup');
Startup.firstFxns[Startup.firstFxns.length++] = 'SDRAMInit';        // this added

*********************************************************************
Of course I would greatly appreciate help ;-)).  I did a lot of searching on forums and did not see this exact question asked.

  • Hello Randy,

    Can you go through the following reference design.

    www.ti.com/.../tidu893.pdf

    www.ti.com/.../tidu853.pdf

    Doing it in TI-RTOS requires to setup the SDRAM before the BIOS is started. Note that bss must not be kept as it is updated during boot and may cause bus faults.

    Regards
    Amit
  • Hello Amit,
    Thanks for the reference design info. The tidu853.pdf does give me performance iinfo which I can use. However, the designs do not address my primary question which is "whether it is possible and or reasonable to modify the project .cmd file to add an .sdram SECTION and put some/any of the ram required by an application in the external SDRAM". I have reliable hardware which allows "C" code access to external SDRAM, but only using a pointer reference.
  • Hello Randy,

    Yes it is possible to put an .sdram section but be sure that any section of code/data being put in this section is not used before SDRAM initialization is done.

    Regards
    Amit
  • Hi Amit,
    Thanks for the response. This encourages me to know that it can be done and I am not on a dead end path. I will continue checking for mistakes.
  • Hello Randy

    One of my colleagues in the past mentioned SDRAM with TI-RTOS needs some considerations

    The default startup code generated by TI compiler initializes all global variables regardless if initialization is required by the application. For the uninitialized global variables, TI startup function initializes them to zero. The startup function is called right after reset before any peripheral is configured. If an uninitialized global variable is declared to external memory, CPU will write zero to the external memory before EPI is properly configured and result in a hard fault error. There may be other unkown side effects caused by this hardware violation.

    The solution to this issue is to change the default linker settings to disable “zero initialize ELF uninitialized sections”. The default value is blank but it is actually “on”.

    If required I would ask my colleague to help you out...

    Regards
    Amit
  • Hi Amit,
    I will look at this new idea carefully. I now have a little better understanding of the startup procedure. I have a project which loads and executes which did not happen before, but still has problems which I am investigating. Thanks again.
    Randy
  • Randy Bulloch said:
    I now have a little better understanding of the startup procedure.

    The boot.asm start-up code in the TI ARM compiler Run Time Library calls the _system_pre_init function after initializing the stack pointer and before performing C/C++ auto-initialization (e.g. zeroing the .bss segment / initializing the .data segment).

    The _system_pre_init function in the Compiler Run Time library is a stub function which does nothing. You can create a own _system_pre_init function in your project which initializes access to the SDRAM RAM. You can then use the linker command file to place any sections for global variables in SDRAM memory.

    The prototype for the _system_pre_init function is:

    int _system_pre_init(void)
    {
        /* Insert code to initialize access to the SDRAM memory. This function is called before the .bss and .data sections
           have been initialized so the core here should only access peripheral registers or local variables allocated on the stack */
    
        /* Return one to indicate the C/C++ auto-initialization should occur */
        return 1;
    }
    

  • Hi Chester,

    I have been attempting to initialize the EPI / SDRAM interface by adding the following to the myproj.cfg file.  Thus having the hardware setup before calling SYS/BIOS.  I am not sure that this .cfg file modification is correct.

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.addUserStartupFunction('&SDRAMInit');     /// this line added

    Is your suggested method another (easier for me to understand) method of accomplishing the same thing?

    Thanks for your help,

    Randy

     

  • I now know that the "BIOS.addUserStartupFunction('&SDRAMInit'); " in my above Reply is NOT a correct solution.
    I am trying to use "_system_pre_init" as recommended by Chester, but my present EPI initialization uses calls to GPIOPinTypeEPI() which violate the restriction of only referencing hardware registers or local variables. So I need to go back to study mode and significantly upgrade my weak/wrong understanding of the boot sequence I am trying to modify.
    Randy
  • Randy Bulloch said:
    I am trying to use "_system_pre_init" as recommended by Chester

    When I made the suggestion of using _system_pre_init I made the mistake of not reading your post correctly. This is because _system_pre_init isn't called by the SYS/BIOS boot.asm start-up code. I am looking at how to get the equivalent functionality in SYS/BIOS.

    Randy Bulloch said:
    EPI initialization uses calls to GPIOPinTypeEPI() which violate the restriction of only referencing hardware registers or local variables.

    Sorry, my description wasn't clear. Other functions can be called as they themselves don't use global variables.

  • Randy Bulloch said:
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.addUserStartupFunction('&SDRAMInit');     /// this line added

    A User Startup Function is called after the C/C++ auto-initialization, and therefore is "too late" in the start-up sequence to be used to enable the SDRAM for use for global variables.

    Instead, try a Reset function:

    var Reset = xdc.useModule("xdc.runtime.Reset");
    Reset.fxns[Reset.fxns.length++] = "&SDRAMInit";

    I have checked by single-stepping the SYS/BIOS startup code that a Reset function is called after the stack pointer has been initialized and before the C/C++ auto-initialization.

    Looking at the code for GPIOPinTypeEPI in TivaWare 2.1.1.71 it should be safe to be called from a SYS/BIOS Reset function, as GPIOPinTypeEPI (and the functions it calls) don't use global variables.

  • Hi Chester,

    Your description was clear, my understanding was limited.  ;-)

    This issue remains an absolute necessity for my projects, but I have a short term interruption to deal with other

    items for a couple of days.

    Randy