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.

IAR project ported to CCS 5.3 (compiler v4.1.3) wont fit in RAM

Other Parts Discussed in Thread: MSP430F2618

I have an MSP430F2618 project in IAR that I am trying to port to CCS for evaluation, but can't get the linker to fit it into RAM.

The IAR RAM memory map is very tight -- in fact I think it is all used !!

  • 0x1100 - 0x129D  (0x19E)  is allocated for some absolute objects (2 volatile vars, and 1 volatile structure)
  • 0x129E - 0x12D3 (0x36) is allocated for DATA16_I (initialized data)
  • 0x12D4 - 0x1401 (0x12E) is allocated for DATA16_Z (zero initialized data)
  • 0x1402 - 0x2E69 (0x1A68) is allocated for DATA16_HEAP
  • 0x2E6C - 0x30FF (0x294) is allocated for CSTACK

The .bss section of the CCS linker map is ... (actually, I hacked the RAM so it was all available to get it to fit and generate the .bss symbols)

.bss       0    00001100    000002a8     UNINITIALIZED
                  00001100    0000012e     API_CRC.obj (.bss)
                  0000122e    000000b0     rts430x.lib : signal.obj (.bss)
                  000012de    00000078                 : xvalues.obj (.bss)
                  00001356    0000002c     API_RRobin.obj (.bss)
                  00001382    00000008     rts430x.lib : _lock.obj (.bss)
                  0000138a    00000008                 : boot.obj (.bss)
                  00001392    00000008                 : feraiseexcept.obj (.bss)
                  0000139a    00000008                 : memory.obj (.bss)
                  000013a2    00000004                 : vars.obj (.bss)
                  000013a6    00000002                 : errno.obj (.bss)

I don't know why the API_CRC.obj file has 0x12E of bss, as this file has NO static or global variables.  I think this is an anomaly of the linker output.  The file API_RRobin.obj looks correct.  I'm wondering if it is the rts430x.lib which is taking up too much space.  Is there a way to get this to a minimal size ??

Any clues as to why the CCS .bss section is so much larger than the IAR .bss section ??

Thanks, Brendan.

  • The size of .bss in API_CRC.obj as shown in the linker map file is not affected by the RTS library.

    Does API_CRC have any static function-local objects?

    The section .bss in API_CRC.obj covers address ranges 0x1100 through 0x122e; please look at the symbol list later in the linker map file to see which symbols fall in that range.  This should give you a good clue where this space comes from.

    Use the command-line utility ofd430 on API_CRC.obj and see what it says about .bss

  • the symbols in the address range 0x100 - 0x122e are defined in other modules, not API_CRC.  This does not seem right and why I think it is a linker quirk/bug.  I don't know why only API_CRC and API_RRobin modules show up in the .bss, when there are clearly more source files that have static/global variables.

    Does rts430 have many global/static variables ??  It seems the IAR run-time library has very few (unless I'm misreading/misunderstanding something)

  • Brendan Simon said:
    the symbols in the address range 0x100 - 0x122e are defined in other modules, not API_CRC.  This does not seem right

    Indeed, that does not sound right, but it does not sound like something the linker would do. 

    What does ofd430 say about API_CRC.obj?  Does it show a .bss section existing in that object file?  If so, the problem happens before the link stage.

    rts430x.lib has very few static-scope variables, unless you are using C++ or floating-point functions.  Those show up as .bss sections from rts430x.lib, as shown in your linker map file fragment.

  • Yes, ofd430 shows a .bss section in API_CRC.obj.

         id name                      load addr  run addr      size align alloc
         -- ----                      ---------  --------      ---- ----- -----
          4 .bss                      0x00000000 0x00000000   0x12e     2   Y

    as an example it has a variable called "lcd_Y"

        4776 lcd_Y           0x000000c2 defined   .bss            global  object 

         2 R_MSP_REL16     0x0000000e 4776 lcd_Y

         2 R_MSP_REL16     0x0000000e 4776 lcd_Y

         1 R_MSP_REL16     0x00000016 4776 lcd_Y

         2 R_MSP_REL16     0x00000016 4776 lcd_Y


    However, lcd_Y is only defined as a global in another file "CONT_BRD_LCD.c"
    uint16 lcd_Y;

    So is this a compiler bug, or something weird I'm doing.

    I've turned all optimizations off.  I'm using packed enums (because i need to and it also matches IAR), which by the way give me linker errors when I use full protram optimization (level 4)

  • I think I've done something weird (in CCS 5.3.0), such that the automated makefile has some rules for API_CRC.c and API_RRobin.c, but none of the other source files.  Make clean doesn't work anymore either, and consequently a Rebuild also doesn't work as expected.  I think I've selected API_CRC.c and API_RRobin.c and tried to individually build them, thinking I could do that to force a build of a particular file and check the output in the console window.

    Could this cause the makefile to be changed ??

    I can't see to get rid of these additional recipes in the Makefile.  I can hand edit them, but they seem to come back when the makefile is regenerated.  Anyone know how to get CCS to forget about these source files and treat them like any other source file ??

  • The existence of those relocations says that there are references to lcd_Y in API_CRC.c, so there must be a declaration visible in API_CRC.c, or one of the header files it includes.  Make sure that declaration is "extern uint16 lcd_Y;"

  • There are no references to lcd_Y in API_CRC.c (or any other file, except for CONT_BRD_LCD.c -- probably should make it static).

    API_CRC.c only includes one file API_Compatibility.h, which is used to defined unit16, unit32, etc.  API_Compatibility.h does not include any other files.

    I think my build system / makefile generation is screwed up.  I'm using the automatic makefile magic in CCS.  It used to work fine, but I've done something to screw it up.  The Makefile generation only seems to see API_CRC.c and API_RRobin.c.  It doesn't seem to be aware of any other sources.  The navigator does show the other files (not greyed) out so I presume CCS believes they are part of the project.

    Any ideas how to reset this in CCS ??  Can I just blow away the Build directory and everything will come good again ??  Or will I lose some the specific Build configuration settings ??

    I'm trying to do fresh rebuild of everything so I know where I stand, but the screwed Makefile/build is blocking me ... sigh ...

  • OK.  Found my problem with the Makefile generation.  I had "program mode" checked => --program_level_compile, -pm

  • I've compared the .bss sections for each of my source files (CCS v IAR) and they are exactly the same size (though a few are 1 byte longer in CCS).

    The IAR C library module uses12 bytes of .bss (errno, new, xgetmemchunk, xxmemxmalloc), whereas the CCS run-time library is 334 bytes !!  So it is definitely the run-time library that is the culprit.

    How can I configure CCS to provide a simialr run-time C library ??  I've tried the specifying the Embedded C++ dialect, and also leaving it blank.  I always seem to get a large runt-time library linked in.

  • For the TI tools, there is no distinct Embedded C++ library.  See SDSCM00037867.

    You've got two object files (signal.obj and feraiseexcept.obj) in your program which aren't really necessary, but are getting dragged in by some other function, probably other RTS library functions.  We should start by figuring out what drags them in. 

    Do you have any floating-point variables or values in your program?  If not, are you using --printf_support=nofloat?

  • There are a number of floating point variables in a table.  Operations include comparisons, multiplication and division.  sprintf and sscanf are used with floating point specifiers.

    I have actually configured CCS to use --printf_support=nofloat, just to see if it would reduce the run-time library but it didn't seem to make any difference.

    I wonder what is dragging in the signal and feraiseexcept modules ??  Is there some kind of cross-reference function call tree output that I can interrogate ??

  • Brendan Simon said:
    Is there some kind of cross-reference function call tree output that I can interrogate ??

    Try call_graph from the cg_xml package.  There is a good chance it will show you what you are looking for.  No promises, though.  It is possible, though unlikely, that the connection to the signal and feraiseexcept modules is not because of any function call, but some data dependence.  A call graph will not show such a relationship.

    Thanks and regards,

    -George

  • I decided to do some minimal tests, based on the CCS template projects (empty with main.c).

    I declared some external floats in the linker script, then did some multiplications and divisions.  The .bss sections was small (0x10 bytes), so it's not floating point causing the issue.

    I did some sprintf and sscanf calls with floating point specifiers.  The .bss section was 0x12.  So it's not sprintf or sscanf.  NOTE: printf does cause some other stuff to be dragged in.  Using printf => .bss = 0x1DE.

    I tried some very simple C++ class and also a derived class.  .bss increased to 0x12A, with rts430x.lib atexit.obj = 0x104 bytes.

    So my guess is that C++ is not well handled or implemented in the run-time library, or drags in stuff that is not needed.

    Any thoughts on this ??  Any work arounds ??

    I'm trying to avoid head back to IAR as I prefer the CCS enviroment -- and it's cross-platform, with hopefully Mac OS X support coming soon too :)

  • Could you please post this very simple C++ example so that I can reproduce the behavior?

  • I have attached a zip file of the entire project directory.  The files of interest are hello.cpp, lnk_msp430f2618.cmd and bss.txt (this is summary of the .bss sections for all test configurations in hello.cpp).  I have CCS v5.3.0.00090 installed, and have done a software update.

    6102.ccs-hello-world.zip

    Cheers, Brendan.

  • Basically, your simple C++ class test is not so simple.  It has a non-trivial destructor; that is, you declared a destructor, and even though it's empty, it exists, and is therefore non-trivial.  This is causing the compiler to drag in a call to delete, which drags in dynamic memory allocation.  The fact that the object is a global object means that the call to delete will be in an atexit-registered function, and atexit uses .bss space for its data structure.  Removing the empty destructor reduces the .bss footprint.

    The "inherit" class test is a bit more tricky.  The bottom line is that because you're calling a non-trivial constructor for a class which has a base class which itself has a non-trivial constructor, the compiler is unable to optimize away the call to "new", which drags in dynamic memory allocation.  In addition, the presence of virtual functions adds a hidden member for the virtual function pointer table, which also foils optimizing away "new."  Removing the "virtual" keyword (it's not needed in this example), removing the destructors from both the base and derived classes, and removing the constructor from the base class together allow the compiler to optimize away the call to "new", which means the atexit data structure doesn't get dragged in, and .bss is much smaller.

  • Fair enough.  All good points.  However the IAR compiler (2008) seems to do a better job.  Here is the output summary for the same hello.cpp test program, with all tests enabled, and using __no_init ... @ <address>; instead of the linker for absolute addresses.

    Module Summary

    ModuleCODEDATACONST
      (Rel) (Rel) (Abs) (Rel)
    ?Cast32f32i 158      
    ?DivMod32s 68      
    ?DivMod32u 68      
    ?DivMod816s 56      
    ?DivMod816u 28      
    ?FLT_EQ 52      
    ?FLT_Extract 84      
    ?FLT_LT 86      
    ?Mul32Hw 48      
    ?Mul32fHw 314      
    ?Mul8Hw 30      
    ?__exit 2      
    ?_exit 16      
    ?abort 6      
    ?cppinit 120 2    
    ?cstart 36      
    ?delop_0 10      
    ?div 52      
    ?div64i 324      
    ?errno   2    
    ?exit 4      
    ?memchr 22      
    ?memcpy 18      
    ?memzero 18      
    ?mul64iHw 152      
    ?printf 30      
    ?putchar 42      
    ?reset_vector 2      
    ?sprintf 56      
    ?sscanf 32      
    ?strchr 16      
    ?strlen 18      
    ?xdnorm 136      
    ?xdscale 154      
    ?xdtento 404     24
    ?xprintflarge
      + shared
    3 394
    96
        25
    ?xprout 24      
    ?xscanffull
      + shared
    2 522
    64
        12
    ?xsprout 12      
    ?xsscin 38      
    ?xstoflt 544     32
    ?xstold 140      
    ?xstoll 200      
    ?xstopfx 246      
    ?xstoull 570     74
    ?xxmemxfree 140      
    ?xxmemxmalloc   4    
    _Add32f 370      
    _Cast32fto32u 12      
    _CmpEq32f 12      
    _CmpLt32f 10      
    _Div32f 320      
    hello 508 15 45 113
    N/A (command line)   660    
    N/A (alignment)        
    Total:11 88468345280

    Segments in Address Order
    SegmentSpaceStartEndSizeKindAlign
    DATA16_AN 1100 - 1103 4 Relative 0
    DATA16_I 1104 Predefined 0
    DATA16_AN 1108 - 110B 4 Relative 0
    1110 - 1113 4
    1118 - 111B 4
    1120 - 1123 4
    1128 - 112B 4
    1130 - 1133 4
    1138 - 113B 4
    DATA16_Z 113C - 1152 17 Relative 1
    DATA16_AN 1180 - 1181 2 Relative 0
    1190 - 1191 2
    11A0 - 11A1 2
    11D0 - 11D0 1
    11F0 - 11F5 6
    CSTACK 2E6C - 30FF 294 Relative 1
    CSTART 3100 - 3123 24 Relative 1
    DATA16_C 3124 - 3237 114 Relative 1
    DATA16_ID 3238 Predefined 0
    DIFUNCT 3238 - 323B 4 Relative 1
    <CODE> 1 323C - 6081 2E46 Relative 1
    RESET FFFE - FFFF 2 Relative 1

    11 884 bytes of CODE memory
    683 bytes of DATA memory (+ 45 absolute )
    280 bytes of CONST memory

    Errors: 1 Warnings: none

  • so where to from here ??

    Is it likely that IAR has a better C/C++ library implementation and/or better C/C++ code generation optimizations ??

    What are the chances of getting the TI C/C++ compiler and libraries to produce equivalent/similar memory maps, at least for .bss as RAM is the most precious resource on MSP430.

  • I don't know.  My quick analysis shows that this would be a non-trivial effort; a deeper analysis is required before we can figure out what would need to be improved.  I've submitted SDSCM00045958 to track this performance issue.