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.

MSP430F5438A Linker file (can not fit code into memory)

Other Parts Discussed in Thread: MSP430F5438A, MSP430F5438, MSP430F5510, MSP430F2618

Hello,

I'm having trouble with getting a program to fit into flash on an MSP430F5438A. The code size is ~50K, and the total flash memory on the MSP430F5438A is 256K. This uC has 4 flash sections (SLAS612C, p. 14).  If I force things around, the program will sometimes load "successfully" but Code Composer will never reset the CPU (the program will just load, but will not execute). 

My entire code size is a little larger than the first flash section defined in the datasheet (SLAS612C, p. 14)

Here's the error (entire project attached as well):


Program will not fit into available memory.  placement with alignment fails for section ".cinit" size 0x34 .  Available memory ranges: FLASH        size: 0xa380       unused: 0x28         max hole: 0x28    lnk_msp430f5438a.cmd   line 124    C/C++ Problem

I understand what the error message means, but if I change any of the FLASH or FLASH2 sections, I create all sorts of strange overlaps, and end up blowing the security fuse. Basically my question is: how do I get a large .code base to allocate all the 256K of memory? I have all optimizations turned on for size in linker options, but I cannot figure out how to specify .code to span all 4 flash sections.

msp430f5438a.cmd

MEMORY

{

.....

    //Here is where the flash range is defined
    FLASH                   : origin = 0x5C00, length = 0xA380
    FLASH2                  : origin = 0x10000,length = 0x35C00

    INT00                   : origin = 0xFF80, length = 0x0002

.....

    INT62                   : origin = 0xFFFC, length = 0x0002
    RESET                   : origin = 0xFFFE, length = 0x0002
}

SECTIONS
{
    .bss        : {} > RAM                /* GLOBAL & STATIC VARS              */
    .data       : {} > RAM                /* GLOBAL & STATIC VARS              */
    .sysmem     : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */
    .stack      : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */

    .text       : {} >> FLASH |  FLASH2   /* CODE                              */ Error usually here
    .text:_isr  : {} > FLASH2             /* ISR CODE SPACE                    */
    .cinit      : {} > FLASH              /* INITIALIZATION TABLES             */
    .const      : {} > FLASH | FLASH2     /* CONSTANT DATA                     */ Error usually here
    .cio        : {} > RAM                /* C I/O BUFFER                      */
    .pinit      : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
    .init_array : {} > FLASH              /* C++ CONSTRUCTOR TABLES            */
    .mspabi.exidx : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */
    .mspabi.extab : {} > FLASH            /* C++ CONSTRUCTOR TABLES            */

    .infoA     : {} > INFOA              /* MSP430 INFO FLASH MEMORY SEGMENTS  */
    .infoB     : {} > INFOB
    .infoC     : {} > INFOC
    .infoD     : {} > INFOD

.......

}


Best regards,


Russell

LEDGoggles_MSP430_Sw_Rev_B_F5438A.zip
  • Hi Russell,

    I don't use CCS.  But it seems to me that the ".cinit : " line should be above the ".text : " line so that that linker places it first.

    To your specific question, it looks like the entire 256KB is configured correctly in the linker script and that the code will span appropriately.  It's just that ".cinit" apparently must reside in the lower 64K.  Again, I don't use CCS, so I don't know if the linker honors the order of sections listed, but I would move all sections that require "FLASH" __above__ all of the sections that can be "FLASH" or "FLASH2".

    Jeff

    PS.  Why does this command file apparently put ISRs in FLASH2 (@ 0x10000 and above)?  That doesn't seem right.

  • Try replacing the following part of the linker script:

     

    .bss : {} > RAM | RAM2 //Global and static variables
    .sysmem : {} > RAM | RAM2 //Dynamic memory alloc
    .stack : {} > RAM2 (HIGH) //Stack
    .text : {}>> FLASH //Code
     .text:_isr : {} > FLASH2 //Interrupt Service Routines
    With:

    .bss : {} > RAM | RAM2 //Global and static variables
    .sysmem : {} > RAM | RAM2 //Dynamic memory alloc
    .data : {} > RAM | RAM2
    .stack : {} > RAM2 (HIGH) //Stack
    .text : {}>> FLASH2 | FLASH //Code
     .text:_isr : {} > FLASH //Interrupt Service Routines

    The reasons for this are:

    1) With CCS 5.2 and MSP430 Compiler v4.1.1 the linker was reporting the warning:

    warning #10247-D: creating output section ".data" without a SECTIONS specification

    As a result the linker was placing the .data section in peripheral space rather than RAM which then leads to a crash. I don't know if you were getting the same warning, but it is a sign that the linker command file was originally generated for an older version of the MSP430 Compiler. Adding the .data section ensures the variables get placed in RAM.

    2) Setting the .text to be placed in FLASH2 in preference to FLASH allows the code to fit without getting the "can not fit code into memory". I don't understand why, but had a similar problem with a MSP430F5438 project.

    3) As Jeff already pointed out the .text:_isr needs to be placed in the first 64Kbytes of memory (as per the default linker script when a new MSP430F5438A project is created).
     

  • Chester,

    This is a logical idea, and certainly fixes the issue of data being stored in the FLASH section, instead of RAM. However, when I make this correction, it blows the security fuse.

    Russell

  • Jeff,

    Those definitions come from TI's CCS linker file via the "User Experience" application for this chip. I'm not sure why that's the case, but with very small code models, it seems to work.

    Seems like everyone using micros at TI use IAR Workbench. If so, why does TI even create this tool at all?

    Russell

  • Hi Russel,

    Russell Lemburg said:

    Seems like everyone using micros at TI use IAR Workbench. If so, why does TI even create this tool at all?

    As far as i know, IAR is much more expensive than CCS.

  • Russell Lemburg said:
    This is a logical idea, and certainly fixes the issue of data being stored in the FLASH section, instead of RAM. However, when I make this correction, it blows the security fuse.

    So that I am looking at the correct information, can you please post:

    a) The current lnk_msp430f5438a.cmd linker command file.

    b) The CCS console build output for a rebuild of the project, to see if there are any #10247-D: creating output section "<section>" without a SECTIONS warnings. See Should linker warning #10247-D really be an error for why these warnings are a sign that the linked program may not run.

    (it the linker ends up placing sections intended for ram in the peripheral address space the start-up code can get stuck continuously generating watchdog resets which means CCS may report that the security fuse is blown)

    c) The LEDGoggles_MSP430_Sw_Rev_B_F5438A.map file produced by the linker, to be able to check where sections have been placed in memory.

  • Chester,

    Thanks for the reply.

    Yes, I've read over the Should linker warning #10247-D really be an error article. This was sort of what we thought was happening, but CCS no longer gives that warning.

    In zip file:

      lnk_msp430f5438a.cmd

      LEDGoggles_MSP430_Sw_Rev_B_F5438A.map

    CCS Build output:

    Description    Resource    Path    Location    Type
    #303-D typedef name has already been declared (with same type)    main.c    /LEDGoggles    line 32    C/C++ Problem
    #70-D integer conversion resulted in truncation    Factory.h    /LEDGoggles    line 204    C/C++ Problem
    #70-D integer conversion resulted in truncation    Factory.h    /LEDGoggles    line 214    C/C++ Problem
    #70-D integer conversion resulted in truncation    Factory.h    /LEDGoggles    line 224    C/C++ Problem

    Thank you

    LEDGoggles_map_and_cmd.zip
  • Looking at the linker command file and map file I can't see any problem with the sections. i.e. appears that the flash and RAM sections are correct.

    The project uses flash above 64Kbyte, has the CCS project selected the "large" memory model?

  • Chester Gillon said:
    The project uses flash above 64Kbyte, has the CCS project selected the "large" memory model?

    On further investigation, when a CCS project is created the CCS Project Properties -> CCS Build -> MSP430 Compiler -> Processor Options -> Specify the code memory model (--code_model) is blank.

    Having the option as "blank" causes the compiler to select the code memory model based upon the type of CPU - small for a CPU module (16-bit register / address bus) and large for a CPUX module (20-bit registers / address bus).

    To confirm the actual settings in use the CCS Project Properties -> CCS Build -> MSP430 Compiler -> Advanced Options -> Assembler Options -> Generate listing file (--asm_listing, -al) can be selected. The resulting .lst file reports the memory model used by the compiler.

    Given that the attached LEDGoggles_MSP430_Sw_Rev_B_F5438A.zip doesn't change the default memory models, it should be using a large code memory model and a small data model which is correct (the map file shows all constants and data are in the lower 32Kbytes).

  • The attached CCS project in the attached LEDGoggles_MSP430_Sw_Rev_B_F5438A.zip contains a system_pre_init.c to "Disable Watchdog timer to prevent reset during long variable initialization sequences".

    Using CCS 5.2.1.00018 and MSP430 compiler v4.1.0 to compile the project in the attached LEDGoggles_MSP430_Sw_Rev_B_F5438A.zip with the lnk2_msp430f5438a.cmd from the attached LEDGoggles_map_and_cmd.zip, the resulting linker map shows that the _system_pre_init function from the project system_pre_init.c gets linked into the executable:

    0001a2b4 0000000a system_pre_init.obj (.text:_system_pre_init)

    Whereas your LEDGoggles.map in the attached LEDGoggles_map_and_cmd.zip shows that the default _system_pre_init function from the run-time-library is used:

    00027af6 00000004 rts430x_lc_sd_eabi.lib : pre_init.obj (.text:_system_pre_init)

    The default default _system_pre_init function from the run-time-library doesn't disable the watchdog, so the executable may suffering from watchdog resets at start-up.

    Has anything in the project, apart from lnk2_msp430f5438a.cmd changed since LEDGoggles_MSP430_Sw_Rev_B_F5438A.zip was attached?

  • Chester,

    This is a good suggestion. I've made sure that we are using the large memory model and small data model (this is correct based on the .map file). I thought I had these compiler arguments enabled.

    CCS has seemed to stop working with Spy-by-Wire as a result of this (I get a "device not recognized" if the FET430UIF is connected in a Spy-by-Wire configuration). However, I managed to get the code to store into memory using JTAG. If I break execution a second or so after running, I get the following runtime message:

    No source available for "_TI_zero_init(unsigned long, unsigned long) at 0x27810"

    Seems like the processor is resetting itself.

    I removed system_pre_init.c and disable the watchdog at the beginning of main().

  • Including rts430x_lc_sd_eabi.lib in the runtime support library and adding system_pre_init.c seemed to work. I'm now able to compile and run the code (~90K), but ONLY WITH JTAG.


    CCS is giving me an "unknown device" if I connect with Spy-by-Wire.

    I could not find any documentation on compiler options for forcing either JTAG or Spy-by-Wire modes in CCS. I know in IAR you can specify either one explicitly.


    Russ

  • Russell,

    from your last post I wasn't sure whether you were able to completely resolve the issue. Could you confirm either scenario?

    As far as the .text: {} >> FLASH2 | FLASH is concerned, the splitting instruction essentially prioritizes splitting and placing .text objects into FLASH2 first and only switches to FLASH when it runs out of FLASH2 space. This is indicated in your map file with most of the code is located in FLASH2 and minimal space is consumed in FLASH.

    I gave your project a quick try, with the latest linker command file that you attached, as well as with some other combinations of placing .text to >/>> FLASH2 | FLASH, and the project seems to build. However, the interrupt vectors, especially the reset vector always shows up as 0xFFFF. This might be due to my hacked-up test setup, but I want to make sure whether you can see the same thing or it was something related to something specific in the code.

    Regarding the system_pre_init.c and its function int _system_pre_init(void), do you plan on adding any code in there other than the watchdog holding line? If not, you can safely remove the file and let CCS use the system default file. You'll need to add the watchdog line to the top of your main() function however.

    Regards,

    Dung

  • Dung,

    The linker file is working now. most of the code should reside in FLASH2. That's now working.

    system_pre_init.c needs to be there. If I disable the watchdog in main, the processor stays in reset.

    The problem I am now having seems to be a result of fixing these other problems. That is, I can no longer debug with Spy-by-Wire. JTAG seems to be the only thing that works.

    Russell

  • Dung Dang said:
    I gave your project a quick try, with the latest linker command file that you attached, as well as with some other combinations of placing .text to >/>> FLASH2 | FLASH, and the project seems to build. However, the interrupt vectors, especially the reset vector always shows up as 0xFFFF. This might be due to my hacked-up test setup, but I want to make sure whether you can see the same thing or it was something related to something specific in the code.

    I just looked the project I built from the attachments. When 'hex430.exe --ti_txt' was run on the generated .out file, the reset vector, TIMER1_A0_VECTOR and TIMER1_A1_VECTOR are showing up as 0x0000!

    There are two warnings 'ignoring .CLINK directive' warnings which are probably related to the vectors being zero:

    **** Build of configuration Debug for project LEDGoggles_MSP430_Sw_Rev_B_F5438A ****

    C:\ti\ccsv5\utils\bin\gmake -k all
    'Building file: ../FFT_430.asm'
    'Invoking: MSP430 Compiler'
    "C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/bin/cl430" -vmspx --abi=eabi -O4 --opt_for_speed=0 -g --include_path="C:/ti/ccsv5/ccs_base/msp430/include" --include_path="C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/include" --define=__MSP430F5438A__ --diag_warning=225 --display_error_number --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --printf_support=minimal --preproc_with_compile --preproc_dependency="FFT_430.pp" "../FFT_430.asm"
    'Finished building: ../FFT_430.asm'
    ' '
    'Building file: ../main.c'
    'Invoking: MSP430 Compiler'
    "C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/bin/cl430" -vmspx --abi=eabi -O4 --opt_for_speed=0 -g --include_path="C:/ti/ccsv5/ccs_base/msp430/include" --include_path="C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/include" --define=__MSP430F5438A__ --diag_warning=225 --display_error_number --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --printf_support=minimal --preproc_with_compile --preproc_dependency="main.pp" "../main.c"
    "..\Factory.h", line 204: warning #70-D: integer conversion resulted in truncation
    "..\Factory.h", line 214: warning #70-D: integer conversion resulted in truncation
    "..\Factory.h", line 224: warning #70-D: integer conversion resulted in truncation
    "../main.c", line 23: warning #303-D: typedef name has already been declared (with same type)
    "C:\DOCUME~1\MR_HAL~1\LOCALS~1\Temp\0328013", WARNING! at line 34570:
    [W0000]
    Section .text:_isr:TIMER1_A0_ISR already has .RETAIN specified -
    ignoring .CLINK directive

    .clink

    No Assembly Errors, 1 Assembly Warning
    'Finished building: ../main.c'
    ' '
    'Building file: ../system_pre_init.c'
    'Invoking: MSP430 Compiler'
    "C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/bin/cl430" -vmspx --abi=eabi -O4 --opt_for_speed=0 -g --include_path="C:/ti/ccsv5/ccs_base/msp430/include" --include_path="C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/include" --define=__MSP430F5438A__ --diag_warning=225 --display_error_number --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --printf_support=minimal --preproc_with_compile --preproc_dependency="system_pre_init.pp" "../system_pre_init.c"
    'Finished building: ../system_pre_init.c'
    ' '
    'Building target: LEDGoggles_MSP430_Sw_Rev_B_F5438A.out'
    'Invoking: MSP430 Linker'
    "C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/bin/cl430" -vmspx --abi=eabi -O4 --opt_for_speed=0 -g --define=__MSP430F5438A__ --diag_warning=225 --display_error_number --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --printf_support=minimal -z --stack_size=256 -m"LEDGoggles_MSP430_Sw_Rev_B_F5438A.map" --heap_size=256 --use_hw_mpy=F5 -i"C:/ti/ccsv5/ccs_base/msp430/include" -i"C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/lib" -i"C:/ti_ccs5_2/ccsv5/tools/compiler/msp430_4.1.0/include" --reread_libs --warn_sections --display_error_number --rom --rom_model -o "LEDGoggles_MSP430_Sw_Rev_B_F5438A.out" "./system_pre_init.obj" "./main.obj" "./FFT_430.obj" -l"libc.a" "../lnk2_msp430f5438a.cmd"
    <Linking>
    "C:\DOCUME~1\MR_HAL~1\LOCALS~1\Temp\0354412", WARNING! at line 52802:
    [W0000]
    Section [1].text:_isr:TIMER1_A0_ISR already has .RETAIN specified -
    ignoring .CLINK directive

    .clink

    No Assembly Errors, 1 Assembly Warning
    'Finished building target: LEDGoggles_MSP430_Sw_Rev_B_F5438A.out'
    ' '

    **** Build Finished ****

  • Hi Dung,

    The linker/memory problems have been fixed. But the MSP430F5438A will only program with JTAG now. This problem seems to be an immediate result of these fixes.

    I've attached the most recent project which programs with JTAG on an EXP430F5438, but no longer programs with Spy-by-Wire (Error: Unknown Device).

    Thank you

    Russ

    LEDGoggles.zip
  • Russell Lemburg said:
    I've attached the most recent project which programs with JTAG on an EXP430F5438, but no longer programs with Spy-by-Wire (Error: Unknown Device).

    When I build that attached project, the reset and timer interrupt vectors are now set correctly in the executable.

    Failure to program can be caused by a program running which crashes the processor before the debugger has a chance to attach to the device.

    The following code initializes the Unified Clock System:

    void initClocks(void)
    {
    UCSCTL0 = 0x1F00; //DCO and MODulation registers (see p. 50 of chip datasheet) DCO=31, MOD=0
    UCSCTL1 = 0x0040; //DCO table for selecting clock ranges on p. 50 of Chip Datashseet DCORSEL = 4
    UCSCTL2 = 0x02DC; //DCO multiplier Divide by 1, multiply by 732
    UCSCTL4 = 0x0333; //Clock source is DCO for ACLK, SMCLK, MCLK
    UCSCTL5 = 0x0550; //Clock divide source (set MCLK to /1, set SMCLK and ACLK to /32)
    UCSCTL6 = 0x01DC; //Set up maximum capacitance for XT1, LF mode, turn off XT2
    }

    It is not commented what frequency crystal is connected to XT1, but assuming a standard XT1 32768Hz crystal that means the MCLK is set to 24MHz. On a MSP430F5438A to allow reliably operation with a MCLK of 24MHz, the PMMCOREV level must first be raised to 3 (see the Recommended Operating Conditions section of the MSP430F5438A datasheet). Looking at the attached code I can't see anything which writes to the PMMCTL0 register. As a result, when initClocks runs to set the MCLK to 24MHz the PMMCOREV will still be at the power on default of zero and the processor will probably crash.

  • Chester Gillon said:
    assuming a standard XT1 32768Hz crystal that means the MCLK is set to 24MHz.

    This is in a risky range even with the correct PMMCOREV setting. Since the DCO mos tlikely won't have the exact frequency available, it will modulate for an average between a higher and a lower frequency. And the higher one could be (worst case) above the allowed maximum.
    With a real 24MHz crystal, there is no modulation and 24MHz are no problem.

  • Chester Gillon said:
    It is not commented what frequency crystal is connected to XT1

    On further investigation the code isn't actually selecting an external XT1 crystal since:

    a) I can't see any code which is selecting P7.0 / P7.1 for the XIN / XOUT module functions, and thus the pins will be I/O.

    b) The write to UCSCTL6 sets XT1BYPASS bit.

    When the initClocks code was tried in a MSP430F5510 (same UCS and DCO Frequency Ranges as a MSP430F5438A) the resulting MCLK was ~20MHz. The XT1LFOFFG and DCOFFG flags were set (DCO bits were maximum of 31). Presumably the device is using the UCS Fail Safe of souring FLLREFCLK from the REFO.

  • We're not using an external crystal, because we do not need very high precision. Is this somehow related to the Spy-by-Wire issues we're having? Perhaps it's related to the frequency difference between 2 and 4-wire JTAG? Quite bizarre.

  • Russell Lemburg said:
    We're not using an external crystal, because we do not need very high precision.

    OK, can you clarify what frequency you want MCLK to be. Is it 24MHz derived from the internal REFO?

    Russell Lemburg said:
    Is this somehow related to the Spy-by-Wire issues we're having?

    Using the initClocks() function I created a test program in a MSP430F5510 (haven't got an actual MSP430F5438A to try - the MSP430F5510 has the same UCS module and DCO frequencies). With the PMMCOREV set to the default level of zero (VCORE measured at 1.4V) then the program didn't crash and I haven't had any debug failures when using a MSP-FET430UIF connected by Spy-By-Wire. i.e. suspect your failures are caused by some other problem, but I don't know what. 

  • I am getting the same error for .cinit not being able to fit.  NOTE: I am using CCS v5.3.0.00067 (RC1) and targeting MSP430F2618.

    "../lnk_msp430f2618.cmd", line 94: error #10099-D: program will not fit into available memory.  placement with alignment fails for section ".cinit" size 0x7d .  Available memory ranges:
       FLASH        size: 0xcebe       unused: 0x0          max hole: 0x0       
    error #10269: output file "xyz-trunk-codecomposer.out" exceeds code size limit

    It looks like the FLASH section is getting filled first.  I tried putting all FLASH sections before any FLASH2 sections but got the same result.

    I then tried replacing the ">> FLASH | FLASH2" with "> FLASH | FLASH2".  The error about .cinit disappeared, but still getting code size limit errors.

    error #10269: output file "xyz-trunk-codecomposer.out" exceeds code size limit

    So what does the >> symbol do, and why is it only used for the .text section ??  I can't find any documentation that describes it :(

  • OK, found it here:

    http://www.ti.com/lit/pdf/slau131

    The >> is used for automatically splitting the section into different areas of a memory region, or across multiple memory regions.

    Now off to find out why my code (ported from IAR) doesn't fit .....

  • Brendan Simon said:
    So what does the >> symbol do, and why is it only used for the .text section ??

    The >> symbol controls "section splitting". For documentation see section 7.5.4.7 Automatic Splitting of Output Sections Among Non-Contiguous Memory Ranges of the MSP430 Assembly Language Tools v 4.1 User's Guide SLAU131G

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

  • I had a similar problem, I'm using an MSP430F5419 with 128K of memory.  The ">>" didn't seem to work, it should have split the code ".text" but didn't, the two Flash segments are separated by the interrupt vectors, my code is reported to be 42.342K and the lower Flash "FLASH" is 41.856K it gave me an error about ".cinit" possibly since it was linked after the code.  Since FLASH2 on my chip is 89.088K I just changed the command to ".text      : {} > FLASH".  I don't know why the linker reports the wrong section or why the ">>" command didn't split my code.  I was using the Large Memory model so I didn't think there would be a problem.

  • Mark James said:
     I was using the Large Memory model so I didn't think there would be a problem.

    THis isn't important for the linker. It just controls which kind of call/ret instructions the compiler generates (16 or 20 bit). The init code, since it is reached through the reset vector, needs to be in low memory. And it is placed after your code because it is loaded from a library while youre code is loaded from explicitely given object files. Also, you don't use large memory model, so it may be (and that's just guessing) that the linker script in this case will put the init values for your global variables into lower FLASH too. Since this section is placed after all global and static variables are collected, it is too placed after your code.

    You can explicitely put some of your functions into FLASH2 by putting the proper pragmas into the source code.

    Sure, teh linker could do a multi-pass run and optimize placing with the results from the first failed pass (that's actually what you do when thinking 'the linker should...') but it hasn't been designed this way.

**Attention** This is a public forum