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.

[DRA829]Question about __TI_auto_init

Hi,Experts

1.Will __TI_auto_init function be called to initialize global variables in the default R5 startup code?

2.This function does not seem to work when I start in xip mode. Why is this?

In my previous post, BU gave me the suggestion that I need to deal with global variables in main.c. https://e2e.ti.com/support/processors/f/791/t/948438?tisearch=e2e-sitesearch&keymatch=%25252520user%2525253A464760   

I look forward to your reply as soon as possible

Regards,

Xie

  • Unlocking this thread

  • Hi Xie,

    The __TI_auto_init is called as a part of the _c_int00. See https://www.ti.com/lit/pdf/SPNU151V Section 6.10.

    1.Will __TI_auto_init function be called to initialize global variables in the default R5 startup code?

    Yes, this is correct. Refer the same section 6.10 for this information.

    2.This function does not seem to work when I start in xip mode. Why is this?

    Can you elaborate here? Do you not call it, or it doesn't work as expected?

    In my previous post, BU gave me the suggestion that I need to deal with global variables in main.c. https://e2e.ti.com/support/processors/f/791/t/948438?tisearch=e2e-sitesearch&keymatch=%25252520user%2525253A464760 

    I just revisited the thread and I see the suggestion was to relocate code which was increasing the size of the binary using the copy_in() function. If you have this in main() it will work for variables/functions which are accessed after main(). Can you explain more on the global variable suggestion you mentioned?

    Regards,

    Karan

  • Hi,Karan

         When we use XIP mode, we will define global variables with initial values and static data in the link file for load address and run address, so that __TI_auto_init will recognize the keywords and copy them from load address to run address? address? Or do you do the copying yourself in the first instruction of main as you told me before?

      Regards,

    Xie

  • Hi Xie,

    I don't think that the copy can happen on its own, you will need to explicitly copy using the copy_in() function. Did you try this and faced an issue or are you yet to attempt this?

    Regards,

    Karan

  • Hi,Karan

            I have tried it and it works when using the copy_in function. If we call copy_in, what does __TI_auto_init do?

      Regards,

      Xie

  • Hi Xie,

    I'm checking this, will get back to you latest by early next week.

    Regards,

    Karan

  • I summarize the question this way:  Given an output section that has different load and run addresses, how does it get copied from the load address to the run address?

    There are two variations to consider. 

    Variation number 1 ... Suppose, in the SECTIONS directive of the linker command file, the output section is written similar to ...

        output_section
        {
           /* input section specifications */
        } run = RAM, load = ROM, table(custom_copy_table)
    
        .ovly > ROM

    Line 4 specifies the memory ranges used for the different run and load addresses.  The table operator creates a copy table associated with a symbol named custom_copy_table.  This copy table is generated into an input section named .ovly.  Line 6 says to create an output section named .ovly.  It is made up of all the input sections also named .ovly, including the one created by the table operator on line 4.  It is allocated an address in the ROM memory range.  In this case, it is the user's responsibility to implement the copy of output_section from ROM to RAM.  This copy must occur before any of the code or data in output_section is used by the program.  The typical way to implement the copy is with C code similar to ...

    #include <cpy_tbl.h>
    
    /* Many lines later, inside a function */
    copy_in(&custom_copy_table);

    The header file cpy_tbl.h, and the function copy_in, are part of the RTS library supplied with the compiler.

    Variation number 2 ... Suppose the output section is written similar to ...

        output_section
        {
           /* input section specifications */
        } run = RAM, load = ROM, table(BINIT)
    
        .binit > ROM

    Compared to variation number 1, the first difference is on line 4, in the argument to the table operator.  It says to add this copy table to the boot-time copy tables.  The copy table is not generated into an input section named .ovly, but into a different input section named .binit.  Line 6 says to create an output section named .binit.  It is made up of all the input sections also named .binit, including the one created by the table operator on line 4.  It is allocated an address in the ROM memory range.  The linker, along with the startup code supplied in the compiler RTS library, arranges for the all the boot-time copy tables to be processed when the program starts.  This happens before the .cinit section (which initializes all the variables in the .data section) is processed.

    For further details, please search the TI ARM assembly tools manual for the sub-chapter titled About Linker-Generated Copy Tables.

    Thanks and regards,

    -George

  • Hi,George

       1.Is there an execution binit in the Boot code of the TDA4 processor? I found no such function in the boot.asm file。

       2.In ARM Assembly Language Tools v20.2.0.LTS I see that we can also use cinit to initialize data and code, so can we use it?

    Regards,

    Xie

  • Unfortunately, I am not familiar with ...

    the Boot code of the TDA4 processor

    I cannot say what it does, or how it is intended to work with the startup code supplied in the compiler RTS library.

    In ARM Assembly Language Tools v20.2.0.LTS I see that we can also use cinit to initialize data and code, so can we use it?

    It only initializes variables that are in the .data section, no code.  The contents of .cinit are processed by the startup code supplied in the compiler RTS library.  It is likely that your program uses this startup code, in which case you already use it.

    Thanks and regards,

    -George

  • Hi,George

    It only initializes variables that are in the .data section, no code.

      As you said, we can use .cinit initializes global data, and use .binit or .ovly to initializes some code run in RAM or DDR?

     Ex:

    .data
    {
    /* input section specifications */
    } run = RAM, load = ROM

    ##################################################
    output_section
    {
    /* input section specifications */
    } run = RAM, load = ROM, table(BINIT)

    .binit > ROM

    OR

    output_section
    {
    /* input section specifications */
    } run = RAM, load = ROM, table(custom_copy_table)

    .ovly > ROM
    #################################################

    Is this correct?

    Regards,

    Xie

         

  • The methods I describe in my first post can be applied to any initialized section, without regard for whether that section contains code or data.

    Thanks and regards,

    -George