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.

MSP430 linker reports "error #10099-D: program will not fit into available memory" even when there is space

Other Parts Discussed in Thread: MSP430F5438

Using CCS Version 5.2.1.00018 and MSP430 compiler v4.1.2 I have sometimes seen the linker report "error #10099-D: program will not fit into available memory" even when there is space.

The steps to reproduce are:
a) Create new empty CCS project for MSP430F5438, using eabi (ELF) output format.

b) Add esparanoia.c to the project, from the Embedded System Paranoia source code in http://www.leshatton.org/wp-content/uploads/2012/01/esp_19.zip

c) Add pre_init.c to the project containing:

#include <msp430.h>

#if !defined(__TI_EABI__)
extern int  __cinit__;  /* define by TI linker == -1 if .cinit isn't loaded */
extern char __bss__;    /* defined by the TI linker to be the start of .bss */
extern char __end__;    /* defined by the TI linker to be the end of .bss */
#endif

int _system_pre_init(void)
{
  WDTCTL = WDTPW+WDTHOLD;

#if !defined(__TI_EABI__)
  /* if .cinit is not loaded, the loader has already initialized .bss */
  if (&__cinit__ != (int *)-1) {
      char *cp;

      /* otherwise, we initialize all .bss to 0 before .cinit is processed */
      for (cp = &__bss__; cp <= &__end__; ) {
          *cp++ = 0;
      }
  }
#endif

  return (1);
}

d) Configure the project settings for the program:
- Set the level of printf support required to full
- Add the predefined symbols NOSIGNAL and NOSETJUMP
- Set the stack size to 1024
- Set the heap size to 1024
- Disable all ULP checks (to reduce warnings)
- Set the data memory model to restricted (to prevent linker warnings of the form #17003-D: relocation from function "atoi" to symbol "_ctypes_" overflowed; the 17-bit relocated address 0x1f4a7 is too large to encode in the 16-bit field)

e) The resulting program is configured to test double precision floating point, and compiles / links / runs. The linker map is esparanoia_double.map

The following size is reported when load in the debugger:

MSP430: Program loaded. Code Size - Text: 99790 bytes Data: 0 bytes.

f) Add the pre-defined symbol SINGLE to the project settings, to change the program to test single precision floating point. Linking now fails with error #10099-D:

**** Build of configuration Debug for project esparanoia_test ****

C:\ti\ccsv5\utils\bin\gmake -k all

'Building file: ../esparanoia.c'

'Invoking: MSP430 Compiler'

"C:/ti/ccsv5/tools/compiler/msp430_4.1.2/bin/cl430" -vmspx --abi=eabi --data_model=restricted -g --include_path="C:/ti/ccsv5/ccs_base/msp430/include" --include_path="C:/ti/ccsv5/tools/compiler/msp430_4.1.2/include" --define=__MSP430F5438__ --define=SINGLE --define=NOSIGNAL --define=NOSETJUMP --diag_warning=225 --display_error_number --diag_wrap=off --silicon_errata=CPU15 --silicon_errata=CPU18 --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --printf_support=full --preproc_with_compile --preproc_dependency="esparanoia.pp" "../esparanoia.c"

"../esparanoia.c", line 276: warning #552-D: variable "E3" was set but never used

'Finished building: ../esparanoia.c'

' '

'Building file: ../pre_init.c'

'Invoking: MSP430 Compiler'

"C:/ti/ccsv5/tools/compiler/msp430_4.1.2/bin/cl430" -vmspx --abi=eabi --data_model=restricted -g --include_path="C:/ti/ccsv5/ccs_base/msp430/include" --include_path="C:/ti/ccsv5/tools/compiler/msp430_4.1.2/include" --define=__MSP430F5438__ --define=SINGLE --define=NOSIGNAL --define=NOSETJUMP --diag_warning=225 --display_error_number --diag_wrap=off --silicon_errata=CPU15 --silicon_errata=CPU18 --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --printf_support=full --preproc_with_compile --preproc_dependency="pre_init.pp" "../pre_init.c"

'Finished building: ../pre_init.c'

' '

'Building target: esparanoia_test.out'

'Invoking: MSP430 Linker'

"C:/ti/ccsv5/tools/compiler/msp430_4.1.2/bin/cl430" -vmspx --abi=eabi --data_model=restricted -g --define=__MSP430F5438__ --define=SINGLE --define=NOSIGNAL --define=NOSETJUMP --diag_warning=225 --display_error_number --diag_wrap=off --silicon_errata=CPU15 --silicon_errata=CPU18 --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --printf_support=full -z --stack_size=1024 -m"esparanoia_test.map" --heap_size=1024 --use_hw_mpy=F5 -i"C:/ti/ccsv5/ccs_base/msp430/include" -i"C:/ti/ccsv5/tools/compiler/msp430_4.1.2/lib" -i"C:/ti/ccsv5/tools/compiler/msp430_4.1.2/include" --reread_libs --warn_sections --display_error_number --diag_wrap=off --rom_model -o "esparanoia_test.out" "./pre_init.obj" "./esparanoia.obj" -l"libc.a" "../lnk_msp430f5438.cmd"

<Linking>

"../lnk_msp430f5438.cmd", line 172: warning #10374-D: Interrupt vector "RTC" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 173: warning #10374-D: Interrupt vector "PORT2" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 174: warning #10374-D: Interrupt vector "USCI_B3" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 175: warning #10374-D: Interrupt vector "USCI_A3" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 176: warning #10374-D: Interrupt vector "USCI_B1" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 177: warning #10374-D: Interrupt vector "USCI_A1" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 178: warning #10374-D: Interrupt vector "PORT1" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 179: warning #10374-D: Interrupt vector "TIMER1_A1" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 180: warning #10374-D: Interrupt vector "TIMER1_A0" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 181: warning #10374-D: Interrupt vector "DMA" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 182: warning #10374-D: Interrupt vector "USCI_B2" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 183: warning #10374-D: Interrupt vector "USCI_A2" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 184: warning #10374-D: Interrupt vector "TIMER0_A1" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 185: warning #10374-D: Interrupt vector "TIMER0_A0" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 186: warning #10374-D: Interrupt vector "ADC12" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 187: warning #10374-D: Interrupt vector "USCI_B0" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 188: warning #10374-D: Interrupt vector "USCI_A0" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 189: warning #10374-D: Interrupt vector "WDT" does not have an interrupt handler routine.

>> Compilation failure

"../lnk_msp430f5438.cmd", line 190: warning #10374-D: Interrupt vector "TIMER0_B1" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 191: warning #10374-D: Interrupt vector "TIMER0_B0" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 192: warning #10374-D: Interrupt vector "UNMI" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 193: warning #10374-D: Interrupt vector "SYSNMI" does not have an interrupt handler routine.

"../lnk_msp430f5438.cmd", line 112: error #10099-D: program will not fit into available memory. placement with alignment fails for section ".cinit" size 0x140 . Available memory ranges:

FLASH size: 0xa380 unused: 0x0 max hole: 0x0

error #10010: errors encountered during linking; "esparanoia_test.out" not built

gmake: *** [esparanoia_test.out] Error 1

gmake: Target `all' not remade because of errors.

**** Build Finished ****

The linker map from the failed link is esparanoia_single_fail.map

g) In the lnk_msp430f5438.cmd file change from the CCS default of:

     .text       : {}>> FLASH | FLASH2     /* CODE                              */

To:

    .text       : {}>> FLASH2 | FLASH     /* CODE                              */

The program now links and runs.

When loaded in the debugger the size is:

MSP430: Program loaded. Code Size - Text: 78632 bytes Data: 0 bytes.

The linker command file is esparanoia_single_works.map

Therefore, there appears to a linker limitation / bug where under some circumstances tries to place too much .text into FLASH, rather than FLASH2, which then causes other sections which can only fit in FLASH to fail to be allocated.

The attached esparanoia.zip contains the linker map files mentioned above, and is the state of the CCS project in the linker fail step f). It doesn't contain the esparanoia.c source file since I am not the author - to build the project you need to get the source file from the esp_19.zip file mentioned above.

esparanoia_test.zip
  • Chester Gillon said:
    - Add the predefined symbols NOSIGNAL and NOSETJUMP

    It should have been NOSETJMP rather than NOSETJUMP. While that changes the result of running the program, since this thread is about a linker error it doesn't matter.

  • Chester Gillon said:
    Therefore, there appears to a linker limitation / bug where under some circumstances tries to place too much .text into FLASH, rather than FLASH2, which then causes other sections which can only fit in FLASH to fail to be allocated.

    When deciding how to place output sections in memory ranges, the linker does not try all possible combinations.  That is not practical.  This problem, generally speaking, has no simple solution.  More background on this topic can be found by searching on the term bin packing problem.

    You already found one solution, which is to change the order of section splitting for the .text section from FLASH | FLASH2 to FLASH2 | FLASH.  Another solution is to allow .cinit to be allocated to either FLASH or FLASH2 ...

        .cinit      : {} > FLASH | FLASH2

    Note you cannot use section spltting (indicated by use of >>) because the .cinit section must be contiguous in memory.

    Thanks and regards,

    -George

  • The linker does prioritize sections which are allocated to only one memory; however, this is only done within one placement phase.  The problem for this test case is that the .text section is placed in phase 1, and the .cinit section is placed in phase 2, by which time .text has already used up all of FLASH. 

    The workaround is as noted: reverse the order of the memories in the placement directive: .text : { } >> FLASH2 | FLASH".  Unfortunately, this is not desirable if the memory model is changed to small code model, so we can't just change lnk_msp430f5438.cmd.  With the order "FLASH | FLASH2", low memory will be used in preference to high memory, which happens to work in small code model, so the linker command file can be shared between large and small model.

    You can't safely place .cinit in FLASH2 if using small data model, because the auto-initialization function is written in C and assumes the C initialization tables themselves are in low memory when using small data model.  This is safe to do if using large or restricted data model (as you are), but it's not safe to do in a linker command file shared with small data memory model.

    The long-term solution for this is not straightforward.  I've submitted enhancement request SDSCM00045294 to investigate this issue further.

  • Archaeologist said:
    Unfortunately, this is not desirable if the memory model is changed to small code model, so we can't just change lnk_msp430f5438.cmd.

    In CCS 5.2.1.00018 the default MSP430 linker command files contain the following in the SECTIONS allocation:

    //#ifdef (__LARGE_DATA_MODEL__)
    .const : {} > FLASH | FLASH2 /* CONSTANT DATA */
    //#else
    // .const : {} > FLASH /* CONSTANT DATA */
    //#endif

    Was this intended to alter the memory allocation according to the memory model selected in the project?

    Given that the conditional compilation is commented out, guess that it isn't supported.

  • Chester Gillon said:
    Was this intended to alter the memory allocation according to the memory model selected in the project?

    Yes.  The fact that this isn't supported is an outstanding enhancement request.  I can't quickly find the SDSCM number.

  • Archaeologist said:
    I can't quickly find the SDSCM number.

    SDSCM00045294.  Feel free to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George

  • hi there !

    i have same problem on 430f47187.. but i don't understand something...

    this problem occurs only with EABI mode ! with COFF, all work fine... WHY ??? what is so different between theses to format ??

    and SDSCM00045294 is open since 2 years ++.... nothing move... 

    i can't imagine TI promote EABI mode and don't correct this BUG (yes it's a BUG !)

    i have check a recent cmd file and there is no workaround at all..

     

    here the link to my post without any solution..

    RE: warning on linking about libmath.a not compatible

    so, what's happend ?

  • Chester Gillon said:

    Unfortunately, this is not desirable if the memory model is changed to small code model, so we can't just change lnk_msp430f5438.cmd.

    In CCS 5.2.1.00018 the default MSP430 linker command files contain the following in the SECTIONS allocation:

    //#ifdef (__LARGE_DATA_MODEL__)
    .const : {} > FLASH | FLASH2 /* CONSTANT DATA */
    //#else
    // .const : {} > FLASH /* CONSTANT DATA */
    //#endif

    Was this intended to alter the memory allocation according to the memory model selected in the project?

    Given that the conditional compilation is commented out, guess that it isn't supported.

    [/quote]

    For posterity, there are three related issues:

    • SDSCM00047925 __LARGE_DATA_MODEL__  not defined
    • SDSCM00048609 __TI_COMPILER_VERSION__ not defined
    • I'm reasonably sure there is no SDSCM number for the feature of supporting C-style preprocessing in the linker command files.  This support was added in 2Q2007 for new compiler major versions.
  • Someone suggested we should link these two threads together: As a note, the newer linker files now have FLASH2 | FLASH so looks like they have changed to be in the order mentioned in the workaround earlier in this thread.