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.

Does startup code need to be modified using C++ in CCS v4

Other Parts Discussed in Thread: LM3S8962, EK-LM3S8962

Hello,

I am using CCS v4 for development on a LM3S8962 Dev board. I am trying to create a c++ project using an existing project in StellarisWare. I completed my code and it compiled fine, but when I try to debug it, the program jumps to an invalid address and crashes without getting to main. I edited the pragma in startup_ccs.cpp for c++ but am wondering if I need to edit the .cmd file.   How should I go about making the project suitable for c++? Does the startup code/ .cmd file differ in a c++ environment from a c environment.   I have read other posts for CodeSourcery but not for CCS tools on how to edit the linker file/startup code for this.

thanks,

Luke

  • Hi Luke,

    You should be able to use the same linker command file. I'm not sure about the startup code however (I'm not too familair with it). If this is StellarisWare startup code, you may want to ping the folks in the Stellaris forum.

    Thanks

    ki

     

  • Luke,

    I just did a quick test with the hello example(on a LM3S9B92, but would expect the same technique to work on other devices). I renamed all the source files in the project to .cpp (including startup_ccs.cpp), did not touch any of the files in the driverlib, grlib etc, modified the #pragma DATA_SECTION to C++ syntax and was able to load and run the program fine.

    I also enabled the "Embedded C++" compiler option and that worked as well.

    Are you able to try this first with one of the unmodified Stellarisware examples to see if it works?

    To further debug where the code is jumping to an invalid address, you can modify the Debug properties to halt the code at the _c_int00 entry point and step through it. Right-click on the project, select Debug Properties. In the Target tab->Auto Run option, uncheck the box to run to main on a program load or restart. This will halt the code at the entry point and single-stepping through it might give you an idea as to where/why it is getting lost.

     

  • Hello,

    I tested a basic example from StellarisWare "Blinky" and I did not modify anything but the #pragma and I followed all of your other instructions. The following is the first instruction followed by the location of the program counter after the first instruction. Should I change something in the linker file so It will load the proper stack pointer?

    0x00000260:   4809     LDR             R0, c_stack

    0xD1220782:   ????????

    Thanks,

     

  • Lucas,

    I could get the "blinky" example for LM3S8962 working by just changing the 2 source files to .cpp and modifying the #pragma. I have attached my project here, perhaps you could import it into your workspace and give it a try. FYI, I am using CCS 4.2.1.

    To import the project into your workspace, go to File->Import, expand CCS and select Existing CCS/CCE Eclipse Projects, in the next screen, select Archive File and browse to the location of blinky.zip. It should discover the project blinky and you can hit Finish.

    7345.blinky.zip

  • Hello again,

    I imported your into my project and tried to debug it and it does the same thing.  Thinking it could be a CCS installation/ update problem, I re-installed CCS 4.2.1, installed all available updates and tried it again but still after that first instruction the program counter jumps to limbo. I don't understand why your system is working but mine is not. Could it be a configuration setting? Is there any files that I could give to you that you could take a look at? This is very frustrating. .

    thanks for your help,

    Luke

  • Are you running the code on a eval kit EK-LM3S8962 or a custom board? I had run the code on a eval kit. Are you able to run the Stellarisware examples as-is, (ie) unmodified for C++?

     

  • I am currently running on eval kit EK-LM3S8962. And yes, I am able to run the examples just fine unmodified for C++. The problem is the C++ modification.

  • That is really strange. Could you check the stack and heap sizes for your project (should be under Build Properties->C/C++ Build->Linker->Basic Options)? My defaults are set to stack size = 256 and no heap. Try increasing these sizes in your project to see if they make a difference. I'm not sure what else could be causing your code to get lost in the startup code especially since the same project works for me.

    I am also attaching a screenshot of my debug properties to compare with yours.

  • ******************************************************************************
                      TMS470 Linker PC v4.6.3                      
    ******************************************************************************
    >> Linked Thu Feb 24 15:56:36 2011
    
    OUTPUT FILE NAME:   <blinky.out>
    ENTRY POINT SYMBOL: "_c_int00"  address: 00000281
    
    
    MEMORY CONFIGURATION
    
             name            origin    length      used     unused   attr    fill
    ----------------------  --------  ---------  --------  --------  ----  --------
      RAM                   00000020   ffffffe0  00000514  fffffacc  RWIX
    
    
    SEGMENT ALLOCATION MAP
    
    run origin  load origin   length   init length attrs members
    ----------  ----------- ---------- ----------- ----- -------
    00000020    00000020    000002e0   000002e0    r-x
      00000020    00000020    000002e0   000002e0    r-x .text
    00000300    00000300    00000214   00000014    rw-
      00000300    00000300    00000014   00000014    rw- .data
      00000314    00000314    00000200   00000000    rw- .stack
    00000518    00000518    00000020   00000020    r--
      00000518    00000518    00000020   00000020    r-- .cinit
    
    
    SECTION ALLOCATION MAP
    
     output                                  attributes/
    section   page    origin      length       input sections
    --------  ----  ----------  ----------   ----------------
    .init_array 
    *          0    00000020    00000000     UNINITIALIZED
    
    .text      0    00000020    000002e0     
                      00000020    0000009c     rtsv7M3_T_le_eabi.lib : memcpy_t2.obj (.text)
                      000000bc    00000094                           : auto_init.obj (.text)
                      00000150    00000058     blinky.obj (.text:main)
                      000001a8    0000004c     rtsv7M3_T_le_eabi.lib : cpy_tbl.obj (.text)
                      000001f4    00000048                           : copy_decompress_rle.obj (.text:decompress:rle)
                      0000023c    00000044                           : exit.obj (.text)
                      00000280    00000034                           : boot.obj (.text)
                      000002b4    00000020                           : args_main.obj (.text)
                      000002d4    00000018                           : _lock.obj (.text)
                      000002ec    00000012                           : copy_decompress_none.obj (.text:decompress:none)
                      000002fe    00000002                           : tdeh_init.obj (.text)
    
    .data      0    00000300    00000014     
                      00000300    00000008     rtsv7M3_T_le_eabi.lib : _lock.obj (.data)
                      00000308    00000008                           : exit.obj (.data)
                      00000310    00000004                           : stkdepth_vars.obj (.data)
    
    .stack     0    00000314    00000200     UNINITIALIZED
                      00000314    00000200     --HOLE--
    
    .cinit     0    00000518    00000020     
                      00000518    0000000f     (.cinit..data.load) [load image, compression = rle]
                      00000527    00000001     --HOLE-- [fill = 0]
                      00000528    00000008     (__TI_handler_table)
                      00000530    00000008     (__TI_cinit_table)
    
    
    LINKER GENERATED COPY TABLES
    
    __TI_cinit_table @ 00000530 records: 1, size/record: 8, table size: 8
    	.data: load addr=00000518, load size=0000000f bytes, run addr=00000300, run size=00000014 bytes, compression=rle
    
    
    LINKER GENERATED HANDLER TABLE
    
    __TI_handler_table @ 00000528 records: 2, size/record: 4, table size: 8
    	index: 0, handler: __TI_decompress_rle
    	index: 1, handler: __TI_decompress_none
    
    
    GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name 
    
    address    name
    --------   ----
    0000023d   C$$EXIT
    00000514   __STACK_END
    00000200   __STACK_SIZE
    00000530   __TI_CINIT_Base
    00000538   __TI_CINIT_Limit
    00000528   __TI_Handler_Table_Base
    00000530   __TI_Handler_Table_Limit
    00000001   __TI_args_main
    000000bd   __TI_auto_init
    000002ed   __TI_decompress_none
    000001f5   __TI_decompress_rle
    00000518   __TI_static_base__
    00000021   __aeabi_memcpy
    00000021   __aeabi_memcpy4
    00000021   __aeabi_memcpy8
    ffffffff   __binit__
    ffffffff   __c_args__
    00000314   __stack
    000002ff   __tdeh_init
    000002b5   _args_main
    00000281   _c_int00
    00000308   _cleanup_ptr
    0000030c   _dtors_ptr
    00000300   _lock
    000002e1   _nop
    000002db   _register_lock
    000002d5   _register_unlock
    00000304   _unlock
    00000241   abort
    ffffffff   binit
    000001a9   copy_in
    00000249   exit
    00000151   main
    00000310   main_func_sp
    00000021   memcpy
    
    
    GLOBAL SYMBOLS: SORTED BY Symbol Address 
    
    address    name
    --------   ----
    00000001   __TI_args_main
    00000021   __aeabi_memcpy
    00000021   __aeabi_memcpy4
    00000021   __aeabi_memcpy8
    00000021   memcpy
    000000bd   __TI_auto_init
    00000151   main
    000001a9   copy_in
    000001f5   __TI_decompress_rle
    00000200   __STACK_SIZE
    0000023d   C$$EXIT
    00000241   abort
    00000249   exit
    00000281   _c_int00
    000002b5   _args_main
    000002d5   _register_unlock
    000002db   _register_lock
    000002e1   _nop
    000002ed   __TI_decompress_none
    000002ff   __tdeh_init
    00000300   _lock
    00000304   _unlock
    00000308   _cleanup_ptr
    0000030c   _dtors_ptr
    00000310   main_func_sp
    00000314   __stack
    00000514   __STACK_END
    00000518   __TI_static_base__
    00000528   __TI_Handler_Table_Base
    00000530   __TI_CINIT_Base
    00000530   __TI_Handler_Table_Limit
    00000538   __TI_CINIT_Limit
    ffffffff   __binit__
    ffffffff   __c_args__
    ffffffff   binit
    
    [61 symbols]
    
    Ive tried changing heap and stack sizes. Debug settings are the same as yours. Check out the attached map file and see if you can see any problems. Could you also send me your .map file and I could look too.

     

  • Your linker command file must be different than the one used in the Stellarisware examples because I don't see separate memory ranges for FLASH and RAM. That might be one of the reasons for the problems you are seeing. I have attached the default linker command file I am using.

    Looking at the project closer, I also noticed that when the startup_ccs.c file is named as .cpp, this warning appears and the interrupt vector section .intvecs is not created at all
    "C:/Stellarisware_working/boards/ek-lm3s8962/blinky/startup_ccs.cpp", line 58: warning: variable "g_pfnVectors" was declared but never referenced
    I may have been mistaken in my earlier comment that just renaming the startup .c file to .cpp would be sufficient. I expect there will be issues due to the .intvecs section not being created (although the simple blinky example does seem to run properly). If you really want to use a C++ file for startup I would suggest posting in the Stellaris forum to see if they can comment further on what other modifications may need to be made to the code.

    In the meantime, you can leave the startup_ccs.c as a C source file, change blinky.c (and other source files) to .cpp and use the attached linker command file. I also attached the link map generated with this build.

    2474.blinky_ccs_ti.zip

  • Aarti,

    The linker command file is the same as yours and it is included in the project so those sections should be created. Please let me know if there is someone there I may be able to talk to so I can get this right.

     

     

  • I suspected your linker command file might be different because the link map file that you had attached earlier looked quite a bit different than mine. Now that you have my link map file you should be able to compare with yours to see if there are differences.

    Since the Stellarisware examples are authored by the Stellaris team and they have more expertise and knowledge on what is required of the startup code, I would suggest asking them in the Stellaris forum if further modification of the code is needed for a C++ environment. The Stellaris forum is at:
    http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/471.aspx

     

  • Aarti, I have been trying to resolve this problem with the customer in this thread:

    http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/471/p/96877/340452.aspx

    However, we are getting stuck on the issue of making the startup file a .cpp and then apparently not exporting a section to the rest of the app.  Here is what I mean:

    In the C version, we have this:

    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
    ...

    This creates the data structure named g_pfnVectors and places it in a section called .intvecs.  This section is referred to in the linker command file to ensure it is located in the proper location required by the processor architecture.
    For the C++ version we have this:
    #pragma DATA_SECTION(".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
    ...
    Which compiles with this warning:
    ../startup_ccs.cpp", line 58: warning: variable "g_pfnVectors" was declared but never referenced
    And this results in the .intvecs section not ending up in the linked image, which means the app will not run.
    I don't understand why the compiler is complaining about this.  There must be a C++ thing I am not aware of.  In C I would say that the compiler cannot possibly know that this data is never referenced because it is global in scope and might be referenced by something outside this .cpp file.  So somehow the C++ compiler is deciding, before the application is linked, that this data structure is not referenced anywhere else and can be deleted.
    Why is this?
    And my final question for now is: is there any reason the startup code cannot remain a .c file and the rest of the app compiled as .cpp and then linked together?  I tried this and it seemed to work.
    Thank you.

  • I also see the compiler warning when compiling startup_ccs.cpp as a C++ file:
    ../startup_ccs.cpp", line 58: warning: variable "g_pfnVectors" was declared but never referenced

    It seems to be a C++ thing (and I'm not that knowledgable in C++ myself) but I was able to get around it by specifying C linkage when declaring g_pfnVectors like:

    #pragma DATA_SECTION(".intvecs")
    extern "C" void (* const g_pfnVectors[])(void
    ) =
    {
       ...

     

     

    When doing this, the .intvecs section is retained in the linked output.

     

    Stellaris Joe said:
    And my final question for now is: is there any reason the startup code cannot remain a .c file and the rest of the app compiled as .cpp and then linked together?  I tried this and it seemed to work.



    I don't see a reason why this can't be done as long as general programming guidelines are followed when mixing C and C++ code. In fact, it was what I had suggested in one of my earlier posts in this thread.

  • The extern "C" does work.  Another solution is to omit the extern "C" and change an option in the Build Properties->TMS470 Linker->Linktime Optimizations. Change the "Eliminate sections not needed in the executable (--unused_section_elimination)" from "       " to "Off".  However, it seems better to use the extern "C" so that the optimization feature can be "on" without eliminating the vector table.

     

     

  • Hi AartiG

    Thanks a lot!!!, i was running into the same issue when using c++ for the stellaris lm4f120h5qr.

    Best Regards.

    Wilbert.