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: Variable initialization

Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI C/C++ Compiler

Hi,

I am encountering problems around variable initialization:

1) i would like to have a global variable that will not be initialized and/or set to zero. if i am assigning the variable to a specific section (pragma DATA_SECTION) it still gets initialized to zero. 

the NOINIT option could/should be a solution but it forces the variable to a dedicated TI.NoInit section and i could not find a way to set a different section if using the #pragma NOINIT.

How can i do this?

2) when i have an initialized global variable (even set to a dedicated section - #pragma DATA_SECTION) the linker/compiler always set a .cinit entry for it and compresses the data. 

how can i prevent this from happening - i don't want this variable to be compressed as i want the initialized data to be loaded with the image (part of the binary) so it will be available BEFORE and C decompression functions?

3) on the TI linker when will i need to use the -u flag (for example i noticed that the generated linker file from sysBios sets a -u _c_int00 --> why was this needed isnt it enough to have a .global / extern in the asm/C file ? when/how/why  this -u is used?

4) If possible, can you emphasize of the difference between NOINIT and NOLOAD?

will - NOLOAD section will not occupy space on the binary but variables will get initialized by C startup routine ?

will - NOINIT section means variable never initialized - was this made only to avoid the variable being initialized to zero by C ? (what happens if a global INITIALIZED variable is set to a NOINIT section? (no warning/error there) ? if variable is never initialized doesn't it means it will behave the same as NOLOAD (no reason for it to take binary space)?

It appear (from test i made) that when setting a section with NOINIT type (on linker) - if variable is initialized, it will be loaded with the initialization and if not initialized will not be touched and both will NOT get compressed (when not using NOINIT section type, the variables, unfortunately, always get compressed /zero initialized).

5) is there a way, when assigning a section to a memory to tell the linker to allocate this section to the memory start / memory end (i could not find a "high" / "low" keywords and also i could not use symbols - the only way so far i could accomplish this is by writing the start address of the memory as a constant number but i would like to use the origin address of the memory)?

Thanks

Guy

Thanks

Guy

Thanks

Guy

  • Guy Mardiks said:

    1) i would like to have a global variable that will not be initialized and/or set to zero. if i am assigning the variable to a specific section (pragma DATA_SECTION) it still gets initialized to zero. 

    the NOINIT option could/should be a solution but it forces the variable to a dedicated TI.NoInit section and i could not find a way to set a different section if using the #pragma NOINIT.

    How can i do this?

    It is not possible to apply both #pragma DATA_SECTION and #pragma NOINIT to the same variable.  There are few different ways you can achieve the same effect.  The one I suspect is most straightforward ... In C use DATA_SECTION, and in the linker command file apply NOINIT.  

    /* C code */
    #pragma DATA_SECTION(var, "mysect:var")
    int var;
    /* Linker command file - inside SECTIONS directive */
        mysect:var > MEMORY_RANGE_NAME, type = NOINIT

    Guy Mardiks said:

    2) when i have an initialized global variable (even set to a dedicated section - #pragma DATA_SECTION) the linker/compiler always set a .cinit entry for it and compresses the data. 

    how can i prevent this from happening - i don't want this variable to be compressed as i want the initialized data to be loaded with the image (part of the binary) so it will be available BEFORE and C decompression functions?

    The linker option --cinit_compression=none disables all compression of the .cinit section.  There is no method to disable cinit compression for just one variable.  Well, there might be a way to do it.  But I haven't thought of one so far.

    Guy Mardiks said:
    3) on the TI linker when will i need to use the -u flag (for example i noticed that the generated linker file from sysBios sets a -u _c_int00 --> why was this needed isnt it enough to have a .global / extern in the asm/C file ? when/how/why  this -u is used?

    I don't know why SYS/BIOS uses -u _c_int00 .  

    The use case for -u that I know ... When you want to force the linker to bring a function out of library, even though there are no calls to that function in the application, you use -u name_of_library_function.  

    Guy Mardiks said:
    4) If possible, can you emphasize of the difference between NOINIT and NOLOAD?

    An explanation of NOLOAD, and other special section types like it, is in the article Linker Special Section Types.

    The type NOINIT is not explained in that article.  A NOINIT section is an uninitialized section like .bss.  Normally, it would be subject to being initialized.  However, you can disable that default behavior by adding type = NOINIT on the linker command file line for that output section.

    Guy Mardiks said:
    5) is there a way, when assigning a section to a memory to tell the linker to allocate this section to the memory start / memory end (i could not find a "high" / "low" keywords and also i could not use symbols - the only way so far i could accomplish this is by writing the start address of the memory as a constant number but i would like to use the origin address of the memory)?

    There is no method for doing that in C.  One method that comes to mind ... Write a header file that is shared between the C code and the linker command file.  Create #define names that are used in both.  Something like this ...

    /* Shared header file */
    #define BASE_ADDRESS 0x20000000
    /* linker command file - MEMORY directive */
    MEMORY_RANGE_NAME : origin = BASE_ADDRESS, ...
    /* C code */
    #pragma LOCATION(var, BASE_ADDRESS)
    int var;

    Thanks and regards,

    -George

  • Hi, Thanks you.
    Regarding allocation to start/end of memory - i meant a syntax for the linker (some linkers support high/low keywords and i was wondering if there is something similar in TI linker to avoid specifying the address directly)

    As for the NOINIT:
    it skips C initialization does that mean it will prevent the variable from entering a compression table (like CINIT) and initialization will happen on image load as part of the binary - at least that is how it seems to behave when i tried but i am not sure of this indeed is the expected/designated behavior?

    regarding the compression tables - and initialized variables being automatically compressed/decompress through the cinit section -is that a TI specific implementation ? i did not see any reference to such behavior on the gnu manual? )i know the c runtime library suppose to set bss to zero but except that i did see any definition about compressing all data)

    i tried adding a table keyword to a section (even though run is equal to load addresses) with setting to no-compression - i paid by another (useless ) table entry but i did see that it seems at least prevent compression (did not enter cinit) - it seemes to behave the same as if i defined instead the section as NOINIT except that with NOINIT there is no additional table entry - is this expected behavior, are my observations indeed correct as to functionality or am i missing something ?

    Thanks
    Guy
  • Guy Mardiks said:
    Regarding allocation to start/end of memory - i meant a syntax for the linker (some linkers support high/low keywords and i was wondering if there is something similar in TI linker to avoid specifying the address directly)

    I'm not sure if it solves your problem.  But the linker does have a HIGH keyword.  Read about it in the section titled Controlling Placement Using The HIGH Location Specifier in the ARM assembly language tools manual.

    Guy Mardiks said:
    As for the NOINIT:
    it skips C initialization does that mean it will prevent the variable from entering a compression table (like CINIT)

    Yes

    Guy Mardiks said:
    and initialization will happen on image load

    No.  The section will correspond to a range of memory where nothing happens during system start.

    Guy Mardiks said:
    regarding the compression tables - and initialized variables being automatically compressed/decompress through the cinit section -is that a TI specific implementation ?

    Yes.  Well, probably yes.  I am not an expert on how the GCC tools handle startup.  But if our solution is similar to GCC, that is unintentional.

    Guy Mardiks said:
    i tried adding a table keyword to a section (even though run is equal to load addresses)

    The table operator is not designed to work that way.  We have no tests which do that.

    Thanks and regards,

    -George

  • Hi,
    About the NOINIT - it i still a unclear at least according to my observation.
    You said that no initialization will take place but my observations are as followed:

    When defining an uninitialized variable in C with the #pragma("NOINIT") it will go into the TI.NOINIT section which is an uninitialized section - as expected.
    if Also i am initializing this variable then it appears that the #pragma("NOINIT") is ignored and the variable goes into the .data section which is initialized and compressed.

    If instead of setting up the NOINIT pragma in C, i am defining a section in the LINKER file and assign it the NOINIT type, then i am assiging the C variable to that section (using #pragma DATA_SECTION) .
    if the variable is not initialized then, as expected the variable goes into the section which is uninitialized.
    if i now also initialize the variable in it C code definition - the variable goes into the assigned section, which is initialized and it is NOT getting compressed. also the initialized data seems to be part of the binary as when loading the image that memory location is written with the initialization values and in any case the C initialization code never "touches" this section.

    Is the above the expected and intended behavior and i can trust and plan upon (a NOINIT linker section is never compressed and its data is saved as part of the binary which is written with the image) or is it some "side effect" and is not intentional and thus should not be "trusted" ?

    Thanks
    Guy
  • Regarding ...

    Guy Mardiks said:
    if Also i am initializing this variable then it appears that the #pragma("NOINIT") is ignored and the variable goes into the .data section which is initialized and compressed.

    When you do that, you should see a diagnostic similar to ...

    "file.c", line 2 (col. 5): warning: variable "var" was declared noinit and should not be initialized

    With regard to forcing an initialized C variable into a section that is marked type = NOINIT in the link command file ...

    Guy Mardiks said:
    Is the above the expected and intended behavior and i can trust and plan upon (a NOINIT linker section is never compressed and its data is saved as part of the binary which is written with the image)

    No

    Guy Mardiks said:
    is it some "side effect" and is not intentional and thus should not be "trusted" ?

    Yes

    Thanks and regards,

    -George

  • Hello, Thanks.
    I am sorry but i am a bit confused. according to your answers, i dont see any difference between NOLOAD and NOINIT.
    NOLOAD is section seems to be always a NOBITS sections - never part of the binary and any initialization done in C seem to be ignored (which is in effect what according to the answers should also be the actual behavior of NOINIT).

    (From the tests, an initialized NOINIT linker section in a PROGBITS section - the entire section and its initialization is part of the binary itself - but if i understood you correctly it is not the intended behavior)

    Also, in light of all of this how is it possible, officially, to achieve an initialized data section which will not get compressed - initialized as part of the binary image? there has to be an official way to do it (CODE_SECTION for TI compiler does not apply to data so this too can't help) . is the only way is by writing it in assembly?

    Thanks
    Guy
  • I apologize for the delay.

    Guy Mardiks said:
    i dont see any difference between NOLOAD and NOINIT.

    My post on April 16 discusses NOLOAD and NOINIT.  I don't know how to improve on that.

    Guy Mardiks said:
    how is it possible, officially, to achieve an initialized data section which will not get compressed

    The only method is to use the linker option --cinit_compression=off.  Unfortunately, there is no method to disable compression for only one section.

    Thanks and regards,

    -George

  • Hi,
    What i meant was that according to the behavior i am seeing:

    when using PRAGMA NOINIT - it effectively creates a NOBITS section which will not be loaded and initiliazed and seems to effectively makes it like a NOLOAD linker section.

    When in the LINKER defining a NOINIT type section and assigning a variable to it, if the variable is initialized the section is created as a PROGBITS sections which mean it will be loaded (with the assigned data) but wont be passed to the C initialization routine - so it will never get compressed (which seems to be a way to get a non compressed section with variables with initialized values (memory was loaded).

    What i am asking is if the above sounds right to you and agrees with what you would expect (in which case the only confusion is with the name of the NO-INIT pragma which is actually a "NO-LOAD" pragma)?

    am i missing something here?

    Thanks
    Guy
  • Please do not apply type = NOINIT to a section that is initialized. That is not a defined combination.  What happens after that cannot be depended upon.  Only apply NOINIT to sections that are uninitialized.

    As for type = NOLOAD ... Sections of this type are used to model code or data that is in ROM or FLASH.  The rest of the current executable file can presume it is present, even though it is not part of the file.  A typical example is a table of constants burned into ROM.  There is no other reason to use NOLOAD.  Note it does not make sense for a NOLOAD section to be uninitialized.

    Thanks and regards,

    -George

  • Thanks for letting me know about the NOINIT.
    As for NOLOAD - in my case it is very sensible to use even for uninitialized areas - otherwise they will be initialized to 0 by the C init process which is no always a good thing - especially if that area is shared by several cores...

    Thanks
    Guy