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.

Error[e16]: Segment DATA16_C is too long for segment definition.

Other Parts Discussed in Thread: MSP430F5659, MSP430F5528

Hello All,

First I'd like to give many thanks to all that have replied to my posts.  You have kept me on target for my porting code from an 8051 to an MSP430F5659 .   I have integrated the many files and now have a space problem. 

I was bringing in the last of the files into the project and got this error:

"Error[e16]: Segment DATA16_C (size: 0x91b9 align: 0x1) is too long for segment definition. At least 0x1239 more bytes needed. The problem occurred while processing the segment placement command "-Z(CONST)DATA16_C,DATA16_ID,TLS16_ID,DIFUNCT,CHECKSUM=8000-FF7F", where at the moment of placement the available memory ranges were "CODE:8000-ff7f"

Reserved ranges relevant to this placement:

8000-ff7f DATA16_C "

this is code I've inherited that works well.  Nobody is going to be keen on me saying I have to rewrite code that works.  Can I swap what is located where, and if so, how do I do that?  I'm in process of trying to decode this error statement but again, I fear my learning curve will be much too long which is why I turn to you folks for help. 

help.  

How do I make this fit? 

many thanx

Dubs

  • It looks like you are "just over" the 64K RAM limit.

    Have you tried to turn on C-optimization? That may help.

  • I'm not too keen to do anything that would change the code. It's not my code, there's a lot of it, and I'd rather relocate chunks if I could. 

     any suggestions?  

     

  • But I did try just to see, and it didn't buy me anything.   Now I need 0x1229 more bytes instead of 0x1239 bytes. 

    I need to move something.   Can I move Variables? structs?  is there someway I can force certain things to be stored someplace else to free up space?   

  • The code has lots of #define macros that either access the port and test a single bit, clear a bit, set a bit, or sometimes do some calculations.   if I made some of these functions that used the stack would that shrink the code that is in RAM. 

    What is stored where?  what is in RAM, Information Memory (flash), Main code memory.  I'd think the #defines were be turned into code during preprocessor, which would make the code size larger, but I'm thinking that would be code memory's problem, not necessarily RAM. 

    help.  

    what can I do?  this is not my code. My job is to port this existing code that has worked so well for so many years into this processor with all functionality. 

  • It looks like what you are running short on is CONST data storage.

    The MSP430F5659 device has 512KB of FLASH.

    Change the memory model to large and update linker file to allow storing CONST and ID data in memory above 0x10000 address.

  • I have tried changing the memory model to large!  the code did (does) compile and link.  I got all happy.  then I tried to download using the Project - Debug and Download option on my IAR compiler  (i'm programming/debugging with a  TI USB FET debugger ) and   first new behavior I see is code seems to recompile again (usually on Debug and Download it just downloads), then it comes up as if the processor is already running without me having to hit the 'run' button.

    So where it is? why did it automatically run?  So I hit the halt button to see where it is in the code and it's stuck in an endless loop in the __data20_memzero:   section in the dissassembly window.  It gets lost before the processor even starts to run.  I can't run it.  

    do you know what's going on/what I have to do?  

  • Dubs Mozz said:
    and it's stuck in an endless loop in the __data20_memzero:   section in the dissassembly window.

    Is it possible that you are trying to initialize too much data in the C init stage that the watchdog timer fires, resetting the processor?

    I would recommend disabling the WDT in the __low_level_init() function.

    Refer to this thread.

  • first thing i do is turn it off:

    int main( void )
    {

    // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;

    SYSINIT_Init_Micro();   // define ports I/O or special function/ direction

    .....

  • Disabling the WDT in main() is no good if the WDT fires before you can get to main().

    This is a common problem when there is a lot of initialized data.

    You need to disable it in __low_level_init() before the C environment is initialized. See the link I posted in my last reply and check the IAR documentation on __low_level_init().

  • i'm a bit confused.   Maybe I'm reading the linked info wrong, it appears they are calling a function __low_level_init() which is a function that has one command, the     WDTCTL = WDTPW + WDTHOLD; command which is the first thing I have in Main() and their function call is the first thing in main().  I'm confused why that is better.  doesn't that mean they have to get to main, then the function call will set up a stack frame, function pointer, yada yada to find where the code of the function resides and then run it.  I'd think simply running the code from inside main without the function call/stack overhead would be faster.   

    what am I missing? 

  • You are awesome! 

    I put the function call outside main and it seems to work!   

    Still more stuff ( a couple more c files with some more constant macros)  to bring in to project, so hopefully the large model will be big enough. 

    I'm looking at the memory organization of the 5659 - what does choosing large memory model do?  where is what?  where are the constants now if they didn't fit in the 512 KB of  RAM?  

  • Dubs Mozz said:
    I put the function call outside main and it seems to work!

    You don't actually explicitly call it at all.

    You provide the implementation. If you do, the linker uses yours, otherwise the linker chooses the default (do nothing) implementation from the run-time library.

    The function gets executed right after reset automatically before the C environment calls your main.

  • Typical (IAR-based) startup sequence (items in [] are symbols):

    1. PC is set to the reset vector contents (ie, load value @ 0xFFFE into PC register) [__program_start]
    2. Stack pointer is loaded
    3. call __low_level_init() [?cstart_call_low_level_init]
    4. If return code from __low_level_init() is 1, then...
    5. Initialize data [?cstart_init_copy]
    6. call into main() [?cstart_call_main]
  • so I am doing:

    int __low_level_init(void) {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT (Watch Dog Timer)
    }


    int main( void )
    {
    // PMMIFG = 0;

    // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;

    .....

    Are you saying that when I create a function like this, and put it before main, the ..., I dont know who, the preprocessor (?) executes what is specified to do inside the function before the program counter goes to main() and begins executing code? 

    do I understand this correctly?  or is this only for __ implicit functions?  does the whole stack frame pointer to the function code happen?   I'm happy it's working, but I have to admit I dont understand what is happening.  If I put another implicit function after __low_level_init() will that function run as well?  I didn't think a function could be run unless the program counting was, well, counting, beginning with the first line of main, and when a function is reached the location of the PC is saved, you jump to where the function code is...yada yada...  

    sorry to be a bother but this is very helpful information 

  • Dubs Mozz said:
    Are you saying that when I create a function like this, and put it before main, the ..., I dont know who, the preprocessor (?) executes what is specified to do inside the function before the program counter goes to main() and begins executing code? 

    No. Not at all. Most of the time the __low_level_init is in it's own file.

    What you are doing is overriding the default function (which does nothing, and thus is usually optimized out by the linker) with one of your one.

    Dubs Mozz said:
    does the whole stack frame pointer to the function code happen?

    The function is called using calla (so it can return).

    Dubs Mozz said:
     If I put another implicit function after __low_level_init() will that function run as well?

    No. This only works for specially defined (named) functions. Read the IAR manuals.

    Dubs Mozz said:
     I didn't think a function could be run unless the program counting was, well, counting, beginning with the first line of main,

    The PC does not get set to main() at reset. It gets set to the code that initializes the environment prior to main().

    Think of it this way... in C++, global objects are constructed before you get to main. Those constructors are executing code. Just because you haven't hit main() yet does not mean that code is not being executed.

    I would suggest turning off the "Run to main" option in your debugger settings. Go into a debug session, hit the "Reset Target" button in the IDE, and then step through in assembly mode to see what's going on prior to main. That's the best way to understand.

  • Hi Brian

    I am facing the same issue and was referring this forum. I am using MSP430F5528. I have changed the memory model to large but can you please tell how to update the linker file to allow storing CONST and ID data in memory above 0x10000 in IAR? Pls elaborate.

    Thanks

    Arnab

  • Dubs Mozz said:

    i'm a bit confused.   Maybe I'm reading the linked info wrong, it appears they are calling a function __low_level_init() which is a function that has one command, the     WDTCTL = WDTPW + WDTHOLD; command which is the first thing I have in Main() and their function call is the first thing in main().  I'm confused why that is better.  doesn't that mean they have to get to main, then the function call will set up a stack frame, function pointer, yada yada to find where the code of the function resides and then run it.  I'd think simply running the code from inside main without the function call/stack overhead would be faster.   

    what am I missing? 

    When a microcontroller like the MSP430 is powered up, the content of RAM contains garbage.
    Before main() is called, the C runtime initialization routine ensures that all global and static variables contains the correct value. It does this by 1) clearing all variables initialized to zero using memset (or a memory-specific version of it). 2) copies values from read-only memory to RAM for non-zero variables using memcpy.
    If this takes longer time than the default watchdog timeout, it will trigger before main() is called. The solution to this is to place the code to disable the watchdog in the __low_level_init() routine, since this is called prior to the memory initialization. See the compiler manual and the file cstartup.s43 for details.
    In addition to simply fixing the hanging problem -- have you checked that you really needs this amount of RAM, and that it must be initialized? For example, if you define a table that you only read, adding a "const" will make it go into read-only memory. If you have a large RAM buffer consider using the __no_init keyword, then it will not be cleared on startup. A good tool for this is reading the linker map file, it will tell you what takes up space in RAM and read-only memory.
        -- Anders Lindgren, IAR Systems, Author of the IAR compiler for MSP430

**Attention** This is a public forum