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.

Force placement of large const array

Other Parts Discussed in Thread: MSP430F2619

My program contains a huge table of the form

                       const unsigned int raw_data[][2] = { ... }


Without the table, everything, including other consts, fits in FLASH using the small data model.  Using the large data model, the linker gathers up all the consts and tries to cram them into FLASH2 which isn't big enough.  It's trying to put 0x10881 bytes into a 0x10000-byte space, while almost half of FLASH is unused.

Is there a way to tell the linker to put all the garden-variety consts into FLASH and put only the monster const into FLASH2?

Thanx

  • Use #pragma DATA_SECTION to arrange for the array to go in a section you name.  Then, in the link command file, place that section in FLASH2.  Details on the pragma are in the Compiler User's Guide.  Since you don't name your device, here are all of them: http://processors.wiki.ti.com/index.php/Before_asking_for_CGT_support#Compiler_User_Guides .  

    Thanks and regards,

    -George

  • I should have included the information that my processor is MSP430F2619

    I was able to get the linker to put the large array into a .raw_array section in FLASH2 as you suggested.  Now I need to know how to reach the elements of the array.  Copying the elements into local variables (raw[0] and raw[1]) leads to compiler complaints that I can't reach the array.  The documentation suggests declaring the raw_data as extern far, but the compiler refuses to admit that "far" is a word used in polite society

                               raw[0] = raw_data[index][0];
                               raw[1] = raw_data[index][1];


    The error message for each of the above statements is:


    relocation from function "MagFilter" to symbol "raw_data" overflowed; the 17-bit relocated address 0x10000 is too large to encode in the 16-bit field (type = 'R_MSP_REL16' (161), file = "./MagFilter.obj", offset = 0x000000aa, section = ".text:MagFilter")

    Another, independent problem is the compiler restriction on array sizes.  The book says 64K.  I have to reduce my array 4 bytes to avoid an "Array too large" error

  • I think you need to use the build option --data_model=large .  But before you do that, read about it in the compiler manual, in the section titled Memory Model.

    Thanks and regards,

    -George

  • George,

    I am using the large data model. 

    The linker map shows all the code and the garden variety consts are loaded in FLASH and my raw data array is loaded in FLASH2.  REAL_DATA is undefined.


    #ifndef    REAL_DATA
        raw[0] = raw_data[index][0];
        raw[1] = raw_data[index][1];
        if (++index > RAW_DATA_SIZE) index = 0;
    #else
        raw[0] = m1;
        raw[1] = m2;
    #endif    
        
         for (channel = 0; channel < 2; channel++)
         {
            sumRaw[channel] = sumRaw[channel] - smoothedRaw[channel] + raw[channel];

    I put a breakpoint at the beginning of the loop.  In the watch window, raw_data[index][0] and raw_data[index][1] are exactly what I put there at compile time.  In the locals window raw[0] and [raw[1] are spectacularly wrong.  The values are what one would find by truncating the address of raw_data[][] to 16 bits.

    How do I persuade the compiler to actually let me use the data in the large memory?

    Thanx for your help,

    JimT

  • George,

    Additional information to go with my last post:

    -vmspx --large_memory_model -g -O0 --define=__MSP430F2619__ --include_path="C:/Program Files/Texas Instruments/ccsv4/msp430/include" --include_path="C:/Program Files/Texas Instruments/ccsv4/tools/compiler/msp430/include" --diag_warning=225 --data_model=large --printf_support=minimal

    -z -m"DDLCode.map" --stack_size=80 --heap_size=80 --use_hw_mpy=16 --warn_sections -i"C:/Program Files/Texas Instruments/ccsv4/msp430/include" -i"C:/Program Files/Texas Instruments/ccsv4/tools/compiler/msp430/lib" -i"C:/Program Files/Texas Instruments/ccsv4/tools/compiler/msp430/include" --reread_libs --rom_model --fill_value=0xDEADDEAD

    Thanx,

    JimT

  • What version of the MSP430 compiler are you using (not the CCS version)?  I suspect that you are using an older version of the tools which cannot handle individual objects that large, thus the documented 64k limitation.  Are you still getting the relocation overflow error when using large data model?

  • Using the Full version of CCS V4 with a 30-day license.  The large data model is selected at compile time and runtime (see post above).  We have several engineers using CCS V4, so I can't switch to CCS V5 until everyone is ready to switch.

  • That's the version of Code Composer, which is not the same as the compiler version. I need to know the version of the compiler, also known as the "Code Generation Tools"

  • Weird!  Code generation tools: TI v3.3.2; Effective code generation tools: 3.3.3.  How does that work?

  • I don't know, someone else will have to address that.  For my purpose, 3.3.2 and 3.3.3 are identical, because 3.3.3 contains only bug fixes.

    I need to brush up on MSP memory models, I'll get back to this in a bit.

  • Jim Taylor said:
    Code generation tools: TI v3.3.2; Effective code generation tools: 3.3.3.  How does that work?

    That means that the project was originally created with Code Generation tools v3.3.2 but the version of CCS you are using has 3.3.3 installed with it, hence that is the "effective" version being used for the build.

  • Jim Taylor said:
    The documentation suggests declaring the raw_data as extern far, but the compiler refuses to admit that "far" is a word used in polite society

    The 'far' keyword is not supported for MSP430.  That document is wrong.  Which document are you looking at?

  • Are you still getting the relocation overflow error when using large data model?

  • Archaeologist,

    The reference to "extern far" is in paragraph 5.9.5 of SLAU132E "MSP430 Optimizing C/C++ compiler v 3.3 User's Guide"

    If I include the pragma

    #pragma DATA_SECTION(raw_data, ".raw_array");

    It puts the data table in the right place, but it produces two instances of the following waning:


    relocation from function "MagFilter" to symbol "raw_data" overflowed; the 17-bit relocated address 0x10000 is too large to encode in the 16-bit field (type = 'R_MSP_REL16' (161), file = "./MagFilter.obj", offset = 0x000000a6, section = ".text:MagFilter")    DDL Code    MagFilter.c    line 67    1339427585380    619

    one of each of these statements

        raw[0] = raw_data[index][0];
        raw[1] = raw_data[index][1];

    It also produces a warning message that says the output file can't be loaded and run.  It does, in fact, load, but the input is fetched from memory starting at address 0x0000 instead of 0x10000.

    If I truncate the data table to use only the remaining space available in the lower flash block and leave out the pragma, it compiles loads and runs normally.  The problem is that the data set is too small for the purpose of the test.

    Thanx for your help,

    JimT

  • The phrase "extern far" does not appear in the latest revision of that document (revision G, for compiler version 4.1).

    The relocation overflow warning should be treated as a fatal error.  It basically means your program will not run correctly, and will have the sort of problem you described.  In fact, the linker specifically warns you that the output file probably won't work, when it says it can't be loaded and run.  We must resolve the relocation overflow problem first.

    Are the data structure raw_data and the function reading from it in two different modules?  If so, what is the declaration of raw_data in MagFilter?

    Is raw_data defined and declared as a const array everywhere it is used?

    [Edit: ask about const in declarations --Archaeologist]

  • Archaeologist,

    The data is in a separate .c file.  I originally tried to put it in a .h file, but the compiler complained that the definition of the array had to be at the module level.  It couldn't be in an #include file because that shows up as one level (or more) below the top level.  There are actually several data files, but all but one at a time are stored with a .txt extension.  Except for their names and the values in the array, they are all declared identically.

    In MagFilter.c the data array is defined as:

    extern unsigned int raw_data[][2];
    extern unsigned int RAW_DATA_SIZE;

    The content of a typical data file, e.g. "Eureka 16-s11.c" is:

    #pragma DATA_SECTION(raw_data, ".raw_array");
    #ifndef TEST_DATA

    const unsigned int raw_data[][2] =
    {
        {2154, 2246}, {2152, 2241}, {2155, 2242}, {2150, 2240}, {2149, 2236}, {2151, 2236}, {2148, 2233},

    . . .

        {2148, 2470}, {2153, 2470}, {2152, 2469}, {2152, 2464}

    };

    #pragma DATA_SECTION(RAW_DATA_SIZE, ".const")

    unsigned int RAW_DATA_SIZE = sizeof(raw_data)/4 - 1;

    #endif /* TEST_DATA */

    The typical length of a data file is 1500 to 3000 lines.

    Thanx,

    JimT

  • Jim Taylor said:
    extern unsigned int raw_data[][2];

    This declaration does not match the actual definition; it lacks "const".  It must match exactly (aside from the first []).  I suspect this is the source of the problem.

  • Archaeologist,

    We are now in the realm of the Law of Conservation of Problems, which states that "Every solution contains within itself the seed of another problem."  A corollary says that the number predicted by the law is a lower limit.

    Adding "const" to the declaration in MagFilter solved the addressing problem!


    Unfortunately, the value of RAW_DATA_SIZE is now 57005, which is rather larger than it used to be (13314).  The actual count of table entries is 13315, and the loop test is     if (++index > RAW_DATA_SIZE) index = 0;

    I would have preferred the original value. I would have accepted 53256 plus or minus 4.  I can't imagine where the extra 3749 came from.

    Thanx,

    JimT


  • This code is in error.  You can't just place things in the .const section, because it is a special section.

    #pragma DATA_SECTION(RAW_DATA_SIZE, ".const")
    unsigned int RAW_DATA_SIZE = sizeof(raw_data)/4 - 1;

    The correct way to do it is:

    const unsigned int RAW_DATA_SIZE = sizeof(raw_data)/4 - 1;

    Don't forget to make all the declarations const.  I can't explain the specific strange value you are getting. Try this fix and let me know what you get. 

  • "Every non-trivial program has at least one bug" - Unknown

    "Every program has at least one bug and can be shortened by at least one instruction — from which, by induction, it is evident that every program can be reduced to one instruction that does not work." - Ken Arnold, says Wikipedia

  • Archaeologist,

    RAW_DATA_SIZE is back where it belongs.  All is well.

    I've been writing too much VB code.  VB is a lot less picky about where you put things.  Of course, it has about 30,000 times as much elbow room, so it can afford to be generous.

    Thanks a million!

    JimT