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.

TMS320F28388D: static variables aren't intialized to zero when mapped to gsram

Part Number: TMS320F28388D


Hello everybody,

we recently updated our cla-code. Now we need the whole LSRAM for the cla-data and cla-prog memory. This is why I mapped the other code to GSRAM.

Since this remapping, some other code fails. The failing code looks like this:

    interrupt void Timer(void){
        volatile static bool runTimeChecker = false;

        /// ***************************************************************************
        /// Check if this cycle is overloaded
        if (runTimeChecker){
            ESTOP0;
            for(;;); //TODO: interrupt got called again before it finished properly -> system is overloaded
        }
        runTimeChecker = true;

        //do some stuff here, details are unimportant for now

        /// ***************************************************************************
        /// Reset to let the runtimeCheck pass
        runTimeChecker = false;
    }

Since the remapping of Section ".bss" (global variables) from LSRAM3 to GSRAM0, this interrupt will always stop at ESTOP0.
The only explanation I can think of is that static variables placed in GSRAM are not initialized. (Maybe there is a restriction I don't know of)

What can I do to make the static variable initialize again without going back to LSRAM?

PS:
CCS: Version: 10.1.1.00004
Compiler: TI v20.2.1.LTS

I have a vacation from tomorrow including the next week, so I might reply to or accept your answer a bit delayed.

Thanks and Regards,

Marcel Kummer.

  • Hi Marcel,

    The only explanation I can think of is that static variables placed in GSRAM are not initialized. (Maybe there is a restriction I don't know of)

    Where is your stack ? It has to be mapped with in 16bit address space on this device so please check that.

    Regards,

    Vivek Singh

  • Hello Vivek,

    my stack is mapped to RAMD1. So this should not be the problem.

    If I map .bss also to RAMD1 everything works fine. But this is only acceptable as a workaround for now.

    Regards,

    Marcel.

  • Ok, thanks. Apart from that I don't see any reason why any variable will not get initialize. On GSxRAM, please note that these are shared between CPU1 and CPU2 and access is allowed based on GSxMSEL register configuration. Please make sure this register configuration is proper to allow access from specific CPU.

    Regards,

    Vivek Singh

  • I checked that multiple times.

    GSRAM0 - 7 are GS_SEL = 0 and GSRAM8-15 are GS_SEL = 1
    To be sure I just checked the registers while being connected.
    Register view shows GSx_MSEL = 0x0000FF00.

    The problem is occurring on CPU1. And it should have full access to the RAM.

    Regards,

    Marcel.

  • Since you are defining this variable inside ISR, it should be considered local variable and not global variable. correct ? Can you put a breakpoint at entry point of ISR and check the value of this variable when code starts (main() entry point) and inside ISR.

    I'll assign this post to compiler team to look if there is any issue in the way variable is defined. 

    Regards,

    Vivek Singh

  • A static variable is not allocated on the stack.  It is in the same section as all the other global variables.  I presume you build with the older COFF ABI and not the newer EABI.  In that case, the static variable runTimeChecker is in a section named .ebss.  To understand how it is initialized, please search the C28x compiler manual for the sub-chapter titled Automatic Initialization of Variables for COFF.  To determine the address of runTimeChecker, add the linker option --mapfile_contents=sym_defs, then search the linker map file for it.  Start your program, run to the start of main, then check that address.  At that point, it should be initialized to 0.

    Thanks and regards,

    -George

  • George,

    Customer mentioned that when they used the LSxRAM for .bss section then it worked fine but when moved that to GSxRAM, it's not working so I am assuming they are using EABI format only.

  • Hello George,

    I just came back from my mentioned vacation, so sorry for my late response.

    As Vivek assumed, we are using the EABI and not the COFF ABI. My code works fine when I map the .ebss into LSRAM or the RAMD1. But those are just workaround solutions.

    Should I still try what you suggested?

    linker option --mapfile_contents=sym

    Thanks and regards,

    Marcel.

  • Should I still try what you suggested?

    Yes.  It would be good to know if, right as main starts, is runTimeChecker set to 0?

    Thanks and regards,

    -George

  • Hello George,

    there are some confusing things I found.

    No matter into which Memory I map the .gss-Section. The variable runTimeChecker always ends up in GSRAM0. The

    map file states, that it is mapped to the .data-Section and not as I assumed into the .gss Section. Why a change of .gss-Memory influences the result I don't understand.

    1)Not working
    If I set the .gss-Section into GSRAM0 the map-file states:
    .data      0    0000d0f6    0000000d     UNINITIALIZED
                      0000d0f6    00000006     rts2800_fpu64_eabi.lib : exit.c.obj (.data)
                      0000d0fc    00000002     SollPosGenerator.obj (.data)
                      0000d0fe    00000002     rts2800_fpu64_eabi.lib : _lock.c.obj (.data:_lock)
                      0000d100    00000002                            : _lock.c.obj (.data:_unlock)
                      0000d102    00000001     Framework.obj (.data:_ZZ9zyklus_x4vE14runTimeChecker)

    With the MemoryBrowser I can see, that the address 0xd102 has the value 0x064C, debugger stopped at main().
    0x0000D0F2 timingGuardCPUTask3
    0x0000D0F2 0000    FFE0
    0x0000D0F4 loopCount
    0x0000D0F4 009E    926F
    0x0000D0F6 __TI_enable_exit_profile_output
    0x0000D0F6 5202    611B
    0x0000D0F8 __TI_cleanup_ptr
    0x0000D0F8 064A    2901
    0x0000D0FA __TI_dtors_ptr
    0x0000D0FA FF40    1E5A
    0x0000D0FC SOLLPOSGENERATOR::testCounter
    0x0000D0FC 0E5F    075A
    0x0000D0FE _lock
    0x0000D0FE 1901    1E4C
    0x0000D100 _unlock
    0x0000D100 065A    1E52
    0x0000D102 zyklus_x4()::runTimeChecker
    0x0000D102 064C    0F52    680E    8354    0652    0746    8AA9    8885    A054    7EC4    0201    0000    0000
    0x0000D10F 0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000
    ...

    2)Working
    If I set the .gss-Section into RAMD1 the map-file states:
    .data      0    0000d000    0000000d     UNINITIALIZED
                      0000d000    00000006     rts2800_fpu64_eabi.lib : exit.c.obj (.data)
                      0000d006    00000002     SollPosGenerator.obj (.data)
                      0000d008    00000002     rts2800_fpu64_eabi.lib : _lock.c.obj (.data:_lock)
                      0000d00a    00000002                            : _lock.c.obj (.data:_unlock)
                      0000d00c    00000001     Framework.obj (.data:_ZZ9zyklus_x4vE14runTimeChecker)

    With the MemoryBrowser I can see, that the address 0xd00c has the value 0x0000, debugger stopped at main().

    zyklus_x4()::runTimeChecker
    0x0000D00C 0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000
    0x0000D019 0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000

    NOTE: Address 0xd102 has the value 0x064C, the same as in case 1) (seems strange)
    0x0000D0E8 0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    FFE0    009E
    0x0000D0F5 926F    5202    611B    064A    2901    FF40    1E5A    0E5F    075A    1901    1E4C    065A    1E52
    0x0000D102 064C    0F52    680E    8354    0652    0746    8AA9    8885    A054    7EC4    0201    0000    0000
    0x0000D10F 0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000    0000

    What makes me curious is, that in both cases the contents of the memoryranges 0x0000D0F3 - 0x0000D10C are the same in both cases. It seems like something is overwriting those contents. But I can't figure out what.

    Thanks and Regards,

    Marcel.

  • I'm confused too.

    No matter into which Memory I map the .gss-Section. The variable runTimeChecker always ends up in GSRAM0. The

    map file states, that it is mapped to the .data-Section and not as I assumed into the .gss Section. Why a change of .gss-Memory influences the result I don't understand.

    I'm not sure what you mean by .gss-Section.  There is no section with that name.  I presume you mean to refer to the .bss section.

    When you build for EABI, the variable runTimeChecker goes in the .data section, not .bss.  In the linker command file, the specification for the .data section is what affects the location of runTimeChecker.  The specification for .bss makes no difference.

    The compiler manual documents this detail.  I concede it is easy to overlook.  Please search the C28x compiler manual for the sub-chapter titled Sections.  Quote ...

    The .data section reserves space for non-const, initialized global and static variables.

    Another quote ...

    The .bss section reserves space for uninitialized global and static variables.

    Focus on the word initialized or uninitialized.  That is the key difference.  Because runTimerChecker is initialized, it goes in .data.

    Does this explanation resolve the problem?

    Thanks and regards,

    -George

  • Hello George,

    I'm sorry, I meant .bss not .gss, like you assumed. I didn't describe my thoughts properly in the last post, maybe I can make it clear now.

    I know, that the runTimeChecker goes into .data and not into .bss. That's what I found out by adding --mapfile_contents=sym_defs to the linker. And you confirmed that with the correct documentation quote. But sadly this information doesn't fix my issue.

    I still have the problem, that when I map the .bss section into RAMD1 runTimeChecker is initialized correctly and if I map it to RAMGS0 it isn't. We know that the .bss section should not influence the runTimeChecker, because that is stored in the .data section. Never the less the change in the .bss Section is influencing the initialization of the runTimeChecker variable.

    With the memory-browser values I shared in the last post, I tried to proof, that the change of the .bss-Section to RAMGS0 is changing the value of runTimeChecker.

    The memory-browser values I posted also show, that the .bss-Section and the .data Section seem to overlap when both are mapped into the GSRAM0. I came to that conclusion because the memory range 0x0000D0F2-0x0000D10C in case 1) has the same content as the range 0x0000D0F4-0x0000D10C in case 2). In case 2) the runTimeChecker variable is mapped to that memory range. This is why I assume .bss and .data are overlapping.

    This overlapping is overwriting the initialization of the runTimeChecker variable, which explains my issue.

    I hope this explains my problem and my conclusions better.

    Regards,

    Marcel.

  • Marcel,

    Your application code is mapped to RAM or flash ? Or do you have any code mapped in Flash ?

    Regards,
    Vivek Singh

  • Hello Vivek Singh,

    It's mapped to Flash.
       .text               : >> FLASH1 | FLASH2 | FLASH3 | FLASH4, ALIGN(4)

    Regrads,

    Marcel.

  • I think that may be the issue here. GSxRAM are used by flash plug-in to load the flash API code and data to program into flash hence user should not use that for any code when using the some part of the code in flash. In this case you should place static variable in flash itself and that is how it should be done in end application also. Can you try that and see if this fixes the issue.

    Regards,

    Vivek Singh

  • I now placed .bss into FLASH1 now. It seems to work now. Thanks for the help. But I must admit, that I am very confused now. (That's why I didn't mark the issue as resolved for the moment)

    Why is it possible to do that? In every TI example I looked into all non const symbols (variables etc.) are always mapped into LSRAM. I never questioned that, because it seems logical to me, that changeable Symbols must be mapped to RAM because otherwise I won't be able to write to those symbols at runtime. If that is wrong then is a mapping like this:

    #if defined(__TI_EABI__)
       .init_array      : > FLASH1, ALIGN(4)
       .bss             : > FLASH1 //can't change to gsram, static variables aren't initialized if I do that
       .bss:output      : > FLASH1
       .data            : > FLASH1
       .sysmem          : > FLASH1
       /* Initalized sections go in Flash */
       .const           : > FLASH5, ALIGN(4)
    #else

    doable?

    Thanks and Regards,

    Marcel.

  • It's not that you can no place them in GSxRAM but if you are using the flash configuration as well then that is restriction because static variables are not initialized as part of cinit but get loaded as part of code and since flash plugin uses that space for loading the plug-in code/data, it gets overwritten. 

    Regards,

    Vivek Singh

  • Okay, thanks for the explanation and your help.