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.

Compiler/TMS320F28379D: "Program will not fit into available memory" but memory size is enough

Part Number: TMS320F28379D

Tool/software: TI C/C++ Compiler

Hi everybody

I get a strange error from the linker:

"error #10099-D: program will not fit into available memory. 
run placement with alignment/blocking fails for section "SetupSec2" size 0xc page 1.
Available memory ranges:
   RAMGS422     size: 0xc          unused: 0xc          max hole: 0xc

How is it possible that it does not fit if section size is equal to available memory size?

  • Francesco,

    If the size of data in SetupSec2 is ltoo arge to fit in single memory section this error will be generated. The solution is too either combine memory sections to create a larger section or to assign mulitple ranges to SetupSec2 in your linker command and have the compiler split the data across multiple memory regions. For more information on how to perform either step, check out htis wikipage:

    http://processors.wiki.ti.com/index.php/C28x_Compiler_-_Understanding_Linking

    Regards,

    Ozino

  • The problem is that my memory segment RAMGS422 has exactly the same size as my SetupSec2, so it should fit into.

    I have this situation in my linker command file

    MEMORY
    
    {
    
    PAGE 1:
    
    RAMGS421    : origin = 0x010100, length = 0x000001
    RAMGS422    : origin = 0x010101, length = 0x00000C
    RAMGS423    : origin = 0x01010D, length = 0x000001
    
    //etc..
    
    }
    
    SECTIONS
    
    {
    
    SetupSec1         : > RAMGS421,  PAGE = 1
    SetupSec2         : > RAMGS422,  PAGE = 1
    SetupSec3         : > RAMGS423,  PAGE = 1
    
    }

    And I have the following globals

    #pragma DATA_SECTION("SetupSec1");
    volatile Uint16 var1
    #pragma DATA_SECTION("SetupSec2");
    volatile Uint32 var2[6];
    #pragma DATA_SECTION("SetupSec3");
    volatile Uint16 var3;

    var2's size is 12 16-word, hence it should fit in RAMGS422

    What is interesting is that if a swap RAMGS421 and RAMGS422, and SetupSec1 and SetupSec2, it works.

    This makes me think that it could be a problem with alignment. Maybe Uint32 are by default aligned on even addresses, but I cannot find any information source about this

  • Do you have any other assignments to RAMGS422? Perhaps that may be contributing to the data not completely fitting. The advanced linker techniques document, http://www.ti.com/lit/an/spraa46a/spraa46a.pdf, will explain how to align the sections. Keep in mind that aligned sections need to start at an addess divisible by a power of 2.

    In terms of alignment, check out this wiki that explains how the alignment is used on C28x devices:

    http://processors.wiki.ti.com/index.php/C2000_Flash_FAQ#Flash_Linker_cmd_file

    Here's a similar forum post discussing the alignment of sections:

    Regards,

    Ozino

  • I neither have any other assignment to RAMGS422, nor ALIGN is used in sections.

    Here are the results of some "experimentations"

    The following works fine:

    #pragma DATA_SECTION("SetupSec1");
    volatile Uint32 var1[6];
    #pragma DATA_SECTION("SetupSec2");
    volatile Uint16 var2;
    #pragma DATA_SECTION("SetupSec3");
    volatile Uint16 var3;
    
    MEMORY
    {
      PAGE 1:
        RAMGS421    : origin = 0x010100, length = 0x00000C
        RAMGS422    : origin = 0x01010C, length = 0x000002
        RAMGS423    : origin = 0x01010E, length = 0x000EF2
    }
    
    SECTIONS
    {
      SetupSec1         : > RAMGS421,  PAGE = 1
      SetupSec2         : > RAMGS422,  PAGE = 1
      SetupSec3         : > RAMGS423,  PAGE = 1
    }
    
    

    But it does not fit if I change the memory as

    MEMORY
    {
      PAGE 1:
        RAMGS420    : origin = 0x010100, length = 0x000001
        RAMGS421    : origin = 0x010101, length = 0x00000C
        RAMGS422    : origin = 0x01010D, length = 0x000002
        RAMGS423    : origin = 0x01010F, length = 0x000EF1
    }

    But if I extend RAMGS421 by 1, it works again

    MEMORY
    {
      PAGE 1:
        RAMGS420    : origin = 0x010100, length = 0x000001
        RAMGS421    : origin = 0x010101, length = 0x00000D
        RAMGS422    : origin = 0x01010E, length = 0x000002
        RAMGS423    : origin = 0x010110, length = 0x000EF0
    }

    In this last case var1 is allocated at 0x010102, and not at the top of RAMGS421 (i.e. 0x010101).
    This confirms my assumption that Uint32 are automatically aligned at even addresses.
    If this is true, to my knowledge it is a feature not documented.




  • When the type is 32-bits or larger (long, float, double, pointers, etc.), then the alignment is to a 2-word (32-bit) boundary.  In this case, that applies to the array of Uint32.  This detail is not explained in the compiler manual.  So, I filed the entry CODEGEN-6787 in the SDOWP system to have the manual corrected.  You are welcome to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George