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.

Stack initialization and C++ initialization

Other Parts Discussed in Thread: AM1808

I use Code Composer Studio for an AM1808. CCS does not have an option to define the stack sizes of the different ARM modes (USR/FIQ/IRQ/SVC/...) so this is done in an init.asm assembler file.

My init.asm defines a routine named "Entry" that setups the stack pointers for each mode. The routine "Entry" is defined as entry-point of the program. After setting up the stacks "Entry" calls _c_int00 to initialize the C/C++ library. Then _c_int00 in turn calls the main routine.

Now I have seen some example where the entry-point routine sets up the stack, then clears the BSS section in a loop and calls __TI_auto_init afterwards.

Is clearing the BSS section manually and then calling __TI_auto_init an appropriate substitution for _c_int00? I tried this solution but as it seems it does not initialize the virtual method tables of C++ classes correctly so calling the base class constructor sometimes fails.

What about calling _c_int00 at the end of the entry-routine? Does it destroy the stack layout that was previously setup or is it ok to call this routine after the stack setup?

 

So my questions are:

1. What is the correct routine to initialize C/C++ after stack setup: _c_int00 or __TI_auto_init?

2. Does __TI_auto_init work with C++ code as it seems to not initialize the VMTs of virtual classes correctly.

 

Thanks in advance.

 

Here the __TI_auto_init solution (at least the concept of it):

====================================================
Entry:

         LDR   r0, _stackptr
         MSR   cpsr_c, #MODE_UND|I_F_BIT
         MOV   sp,r0
         SUB   r0, r0, #UND_STACK_SIZE

         ; setup ABT, FIQ, IRQ, SVC, USR/SYS
         ...

Clear_Bss:

         LDR   r0, _bss_start    
         LDR   r1, _bss_end      
         SUB   r1,r1,#4
         MOV   r2, #0
Loop:
         STR   r2, [r0], #4      
         CMP   r0, r1
         BLE   Loop              

         LDR   r10, __TI_auto_init
         BLX   r10               

         ; jump to main()
         ...

====================================================

The _c_int00 solution:

====================================================
Entry:

         LDR   r0, _stackptr
         MSR   cpsr_c, #MODE_UND|I_F_BIT
         MOV   sp,r0
         SUB   r0, r0, #UND_STACK_SIZE

         ; setup ABT, FIQ, IRQ, SVC, USR/SYS
         ...

         LDR   r0, __c_int00
         BX    r0

====================================================

 

 

  • An update to my previous post.

    I looked into the code of CCSv5 for _c_int00 in the boot.asm (part of rtssrc.zip) assembler file. As it turns out _c_int00 is not that complex. It does the following:

    1. switch to USR mode
    2. setup USR mode stack sp to "__stack + __STACK_SIZE" (= __STACK_END)
    3. set main_func_sp to the start of the USR stack (= USE mode sp set in step 2) for SDP analysis
    4. call __TI_auto_init to setup data sections
    5. call the main routine (_args_main)
    6. call the exit handler (exit)

    That means that calling _c_int00 at the end of init.asm is a bad idea because _c_int00 will map the USR/SYS stack to __STACK_END -- the memory area that init.asm already assigned to the UND stack. So some of the stacks will use the same memory areas so crashes are unavoidable.

    A second problem with _c_int00 is that it will stay in the USR mode set in step 1. This way it is not possible to initialize the Pinmuxer or enable interrupts in the main routine without switching to the priviledged mode. It is odd that the _c_int00 that is provided with the LogicPD board of the AM1808 eXperimeter kit (in AM1808_rts.lib) does not switch to USR mode but stays in SYS mode.

    As _c_int00 is not a solution I looked into the solution with the direct call __TI_auto_init that I mentioned in the first post:
    Unfortunately _stackptr was an alias for __stack which is wrong. It should have been __STACK_END instead as __stack points to the lower end of the stack and thus assigns memory of the .text section to the stacks, causing nasty side effects. So the C++ VMT problem was not directly related to __TI_auto_init but to corrupt stacks.

     

    A few questions still remain:

    1. Is clearing the BSS section necessary? _c_int00 does not seem to do it.
    2. What is main_func_sp good for (is the SDP analysis mentioned in boot.asm done by CCS)? Will there be a crash if this variable is not inited?

    Thanks in advance.

     

  • First off, sorry for the delay in answering.  I'm not sure how that happened.

    Tobias Gunkel said:
    Is clearing the BSS section necessary? _c_int00 does not seem to do it.

    No, it is not necessary.  For details see this part of a Wiki article.  Note the .bss section contains all the uninitialized static storage duration objects discussed in the article.

    Tobias Gunkel said:
    What is main_func_sp good for

    It is related to the stack depth profiler.  If you don't use that feature, you can ignore it.

    Tobias Gunkel said:
    (is the SDP analysis mentioned in boot.asm done by CCS)?

    No.

    Tobias Gunkel said:
    Will there be a crash if this variable is not inited?

    No.

    Thanks and regards,

    -George