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.

Compiler/TMS320F28075: .ebss section zero initialisation - RUN_START() and RUN_SIZE()

Part Number: TMS320F28075


Tool/software: TI C/C++ Compiler

;//###########################################################################
;//
;// FILE:  F2807x_CodeStartBranch.asm
;//
;// TITLE: Branch for redirecting code execution after boot.
;//
;// For these examples, code_start is the first code that is executed after
;// exiting the boot ROM code.
;//
;// The codestart section in the linker cmd file is used to physically place
;// this code at the correct memory location.  This section should be placed
;// at the location the BOOT ROM will re-direct the code to.  For example,
;// for boot to FLASH this code will be located at 0x3f7ff6.
;//
;// In addition, the example F2807x projects are setup such that the codegen
;// entry point is also set to the code_start label.  This is done by linker
;// option -e in the project build options.  When the debugger loads the code,
;// it will automatically set the PC to the "entry point" address indicated by
;// the -e linker option.  In this case the debugger is simply assigning the PC,
;// it is not the same as a full reset of the device.
;//
;// The compiler may warn that the entry point for the project is other then
;//  _c_init00.  _c_init00 is the C environment setup and is run before
;// main() is entered. The code_start code will re-direct the execution
;// to _c_init00 and thus there is no worry and this warning can be ignored.
;//
;//###########################################################################
;// $TI Release: F2807x Support Library v3.06.00.00 $
;// $Release Date: Mon May 27 06:53:35 CDT 2019 $
;// $Copyright:
;// Copyright (C) 2014-2019 Texas Instruments Incorporated - http://www.ti.com/
;//
;// Redistribution and use in source and binary forms, with or without 
;// modification, are permitted provided that the following conditions 
;// are met:
;// 
;//   Redistributions of source code must retain the above copyright 
;//   notice, this list of conditions and the following disclaimer.
;// 
;//   Redistributions in binary form must reproduce the above copyright
;//   notice, this list of conditions and the following disclaimer in the 
;//   documentation and/or other materials provided with the   
;//   distribution.
;// 
;//   Neither the name of Texas Instruments Incorporated nor the names of
;//   its contributors may be used to endorse or promote products derived
;//   from this software without specific prior written permission.
;// 
;// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
;// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
;// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
;// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
;// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
;// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
;// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
;// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
;// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
;// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
;// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;// $
;//###########################################################################

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

WD_DISABLE  .set  1    ;set to 1 to disable WD, else set to 0

    .ref _c_int00
    .global _r_start_ebss
    .global _r_size_ebss
    .global code_start

***********************************************************************
* Function: codestart section
*
* Description: Branch to code starting point
***********************************************************************

    .sect "codestart"

code_start:
    .if WD_DISABLE == 1
        LB wd_disable       ;Branch to watchdog disable code
    .else
    	;Code to zero initialise ebss section before calling _c_init00 which performs direct initialisations
    	movl XAR0,#_r_start_ebss
    	mov AL,#0
    	mov AH,#(_r_size_ebss - 1)
    	rpt AH || mov *XAR0++,AL
    	;End of zero-init code
        LB _c_int00         ;Branch to start of boot._asm in RTS library
    .endif

;end codestart section

***********************************************************************
* Function: wd_disable
*
* Description: Disables the watchdog timer
***********************************************************************
    .if WD_DISABLE == 1

    .text
wd_disable:
    SETC OBJMODE        ;Set OBJMODE for 28x object code
    EALLOW              ;Enable EALLOW protected register access
    MOVZ DP, #7029h>>6  ;Set data page for WDCR register
    MOV @7029h, #0068h  ;Set WDDIS bit in WDCR to disable WD
    EDIS                ;Disable EALLOW protected register access
    ;Code to zero initialise ebss section before calling _c_init00 which performs direct initialisations
    movl XAR0,#_r_start_ebss
    mov AL,#0
    mov AH,#(_r_size_ebss - 1)
    rpt AH || mov *XAR0++,AL
    ;End of zero-init code
    LB _c_int00         ;Branch to start of boot._asm in RTS library

    .endif

;end wd_disable

    .end

;//
;// End of file.
;//

MEMORY
{
PAGE 0 :  /* Program Memory */
          /* Memory (RAM/FLASH) blocks can be moved to PAGE1 for data allocation */
          /* BEGIN is used for the "boot to Flash" bootloader mode   */

   BEGIN           	: origin = 0x080000, length = 0x000002
   RAMM0           	: origin = 0x000122, length = 0x0002DE
   RAMD0           	: origin = 0x00B000, length = 0x000800
   RAMLS0          	: origin = 0x008000, length = 0x000800
   RAMLS1          	: origin = 0x008800, length = 0x000800
   RAMLS2      		: origin = 0x009000, length = 0x000800
   RAMLS3      		: origin = 0x009800, length = 0x000800
   RAMLS4      		: origin = 0x00A000, length = 0x000800
   RESET           	: origin = 0x3FFFC0, length = 0x000002

   /* Flash sectors */
   FLASHA           : origin = 0x080002, length = 0x001FFE	/* on-chip Flash */
   FLASHB           : origin = 0x082000, length = 0x002000	/* on-chip Flash */
   FLASHC           : origin = 0x084000, length = 0x002000	/* on-chip Flash */
   FLASHD           : origin = 0x086000, length = 0x002000	/* on-chip Flash */
   FLASHE           : origin = 0x088000, length = 0x008000	/* on-chip Flash */
   FLASHF           : origin = 0x090000, length = 0x008000	/* on-chip Flash */
   FLASHG           : origin = 0x098000, length = 0x008000	/* on-chip Flash */
   FLASHH           : origin = 0x0A0000, length = 0x008000	/* on-chip Flash */
   FLASHI           : origin = 0x0A8000, length = 0x008000	/* on-chip Flash */
   FLASHJ           : origin = 0x0B0000, length = 0x008000	/* on-chip Flash */
   FLASHK           : origin = 0x0B8000, length = 0x002000	/* on-chip Flash */
   FLASHL           : origin = 0x0BA000, length = 0x002000	/* on-chip Flash */
   FLASHM           : origin = 0x0BC000, length = 0x002000	/* on-chip Flash */
   FLASHN           : origin = 0x0BE000, length = 0x002000	/* on-chip Flash */

PAGE 1 : /* Data Memory */
         /* Memory (RAM/FLASH) blocks can be moved to PAGE0 for program allocation */

   BOOT_RSVD       : origin = 0x000002, length = 0x000120     /* Part of M0, BOOT rom will use this for stack */
   RAMM1           : origin = 0x000400, length = 0x000400     /* on-chip RAM block M1 */
   RAMD1           : origin = 0x00B800, length = 0x000800

   RAMLS5      : origin = 0x00A800, length = 0x000800

   RAMGS0      : origin = 0x00C000, length = 0x001000
   RAMGS1      : origin = 0x00D000, length = 0x001000
   RAMGS2      : origin = 0x00E000, length = 0x001000
   RAMGS3      : origin = 0x00F000, length = 0x001000
   RAMGS4      : origin = 0x010000, length = 0x001000
   RAMGS5      : origin = 0x011000, length = 0x001000
   RAMGS6      : origin = 0x012000, length = 0x001000
   RAMGS7      : origin = 0x013000, length = 0x001000
}

SECTIONS
{
   /* Allocate program areas: */
   .cinit              : > FLASHB      PAGE = 0, ALIGN(4)
   .pinit              : > FLASHB,     PAGE = 0, ALIGN(4)
   .text               : >> FLASHB | FLASHC | FLASHD | FLASHE | FLASHF | FLASHG      PAGE = 0, ALIGN(4)
   codestart           : > BEGIN      PAGE = 0, ALIGN(4)

   /* Allocate uninitalized data sections: */
   .stack              : > RAMGS2        PAGE = 1
   .ebss               : >> RAMLS5 | RAMGS0 | RAMGS1, PAGE = 1
   						RUN_START(_r_start_ebss),
   						RUN_SIZE(_r_size_ebss)

   .esysmem            : > RAMLS5       PAGE = 1

   /* Initalized sections go in Flash */
   .econst             : >> FLASHH | FLASHI | FLASHJ      PAGE = 0, ALIGN(4)
   .switch             : > FLASHB      PAGE = 0, ALIGN(4)

   .reset              : > RESET,     PAGE = 0, TYPE = DSECT /* not used, */

   ramgs0           : > RAMGS0,    PAGE = 1
   ramgs1           : > RAMGS1,    PAGE = 1

#ifdef __TI_COMPILER_VERSION__
   #if __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} LOAD = FLASHD,
                         RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_SIZE(_RamfuncsLoadSize),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         RUN_SIZE(_RamfuncsRunSize),
                         RUN_END(_RamfuncsRunEnd),
                         PAGE = 0, ALIGN(4)
   #else
   ramfuncs            : LOAD = FLASHD,
                         RUN = RAMLS0 | RAMLS1 | RAMLS2 |RAMLS3,
                         LOAD_START(_RamfuncsLoadStart),
                         LOAD_SIZE(_RamfuncsLoadSize),
                         LOAD_END(_RamfuncsLoadEnd),
                         RUN_START(_RamfuncsRunStart),
                         RUN_SIZE(_RamfuncsRunSize),
                         RUN_END(_RamfuncsRunEnd),
                         PAGE = 0, ALIGN(4)   
   #endif
#endif

    /* The following section definition are for SDFM examples */
   Filter1_RegsFile : > RAMGS1,	PAGE = 1, fill=0x1111
   Filter2_RegsFile : > RAMGS2,	PAGE = 1, fill=0x2222
   Filter3_RegsFile : > RAMGS3,	PAGE = 1, fill=0x3333
   Filter4_RegsFile : > RAMGS4,	PAGE = 1, fill=0x4444
   Difference_RegsFile : >RAMGS5, 	PAGE = 1, fill=0x3333
}

/*
//===========================================================================
// End of file.
//===========================================================================
*/

Hello,

I am trying to zero initialise the .ebss section during the code_start routine.

To do so I try and acquire the .ebss start address and .ebss size.

Then making them available to the code_start routine, I attempt to run a loop which zero-inits the entire section.

But when I look at both ebss start address and ebss size in the watch window, they both equal 0x003FFFFF.

Please see my linker file and assembly code attached (not sure how to paste formatted .cmd and .asm code into the forum).

I have tried;

- RUN_START(), RUN_SIZE().

- START(), SIZE() (which I believe is equivalent to...)

- LOAD_START(), LOAD_SIZE().

but both combinations always return 0x003FFFFF for both .ebss start and .ebss size.

Not sure where I am going wrong calling this directive, any help with this would be greatly appreciated.

Louis

  • Louis,

    I've reproduced the issue you are having.  The problem is that you allocated the .ebss section to potentially split among multiple memory ranges in your linker .cmd file.

    .ebss : >> RAMLS5 | RAMGS0 | RAMGS1, PAGE = 1
    RUN_START(_r_start_ebss),
    RUN_SIZE(_r_size_ebss)

    This seems to confuse the symbol value computation done to produce _r_start_ebss and _r_size_ebss.  For that matter, how would you be able to write a single loop to initialize the section if it were in fact split between two discontinuous memory ranges?

    If you get rid of the ">>", things will work.  I'd suggest combining the RAMGS0 and RAMGS1 memories in the MEMORY section of your .cmd file.  Call it RAMGS01.  Then, just allocate the .ebss there.  Hopefully it fits.

    Regards,

    David

  • Thanks, David.

    Louis,

    A couple of other things I wanted to point out.  A feature unique to this platform is that the RAM blocks are automatically initialized to zero on a reset event.  This applies both to a power-on reset, and to a 'warm' reset, such as a watchdog timeout or other event which toggles the /XRSn pin.

    Also, if you want to initialize the ram deliberately in the code, there are RAM INIT registers which will allow you to do the job.  See section 3/15/17 for the register names and descriptions.  E.g. the GSxINIT register contains bits to select which blocks to initialize, and the GSxINITDONE register contains bits to poll for completion.

    If you are initializing with the assembly code you sent, be a little careful about the case where the watchdog is left running while you are in the init loop.  Initializing a large memory array in this way can cause a WD timeout, in which case your routine will never exit.  Just something to watch for.

    Regards,

    Richard

  • Hi Richard and David,

    Thank you very much for the help.

    David,

    That solution works great for my specific question.

    Richard,

    Your suggestions are greatly appreciated and I think I will go the route of the RAM init registers.

    In response to the auto-initialized variables comment; I have seen in my current setup that the RAM doesn't get initialised to zero before run time when declaring global arrays, even when I explicitly set the array to all zeros using syntax; uint8_t myArray[512] = {0};

    This seems to only set the first element of the array to 0 and for things like comms buffers I don't really want to write 512 0's in the declaration/definition.

    I found a wiki that seems to justify why this is;

    https://processors.wiki.ti.com/index.php/Uninitialized_Static_Objects_Not_Set_to_Zero_in_COFF

    And also the documentation for the compiler (TMS320C28x Optimizing C/C++ Compiler v19.6.0.STS) states explicitly that;

    "in COFF ABI mode the compiler itself makes no provision for initializing to 0 otherwise
    uninitialized static storage class variables at run time. It is up to your application to fulfill this requirement."

    And I couldn't find a compiler option in Code Composer Studio that allows me to change ABI to EABI, which I believe performs the auto-initialization. As a result I think manually performing the initialisation before calling the run time setup routine (_c_init00) is probably the quickest way to get to some zeroed RAM.