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.

Relocation errors in large data model



I have been reading and struggling with this but am at a loss as to how to fix this error.

I am using CCSv5.5 w/ compiler 4.2.2.  I'm programming on an MPS430F5659 in large code and large data models.  I am using an unmodified linker command file.  I have selected 'eabi' and 'mspx'.

I have about 67KB of code and about 32KB of data.

When I compile, I get a huge number of:

"../main.c", line 263: warning #17003-D: relocation from function "USCI_A0_ISR" to symbol "DBG_RxData" overflowed; the 20-bit relocated address 0xf45ca is too large to encode in the 16-bit field (type = 'R_MSP430X_ABS16' (15), file = "./main.obj", offset = 0x00000014, section = ".text:_isr:USCI_A0_ISR")

It seems that every variable, not just those in the isr's, are affected.

Nothing that I have read seems to address or help my particular situation.

Any suggestions would be welcome.  Surely there is some simple setting that I am missing.

Thanks


UPDATE:

I've found that by reducing an array size down so that all data fits within a single 16KB boundary, all of the relocation errors disappear.  If I allow the data size to grow to larger than 16KB, the relocation errors reappear.

I've verified that I am using large code and data models.

So, is large data model not working?

  • Well, 0xf45ca isn't a valid address at all. I don't know of any MSP with the full 1MB Address space covered with ram or flash. So 0xf45ca is vacant memory.

    I guess I know what happened, and yes, it seems to be a compiler bug. It has to do with the indexed mode in assembly instructions.
    To load a value form an array, the compiler usually uses an instruction of type
    MOV x(Ry),z.
    Now x (and maybe z) are constants, while Ry is a register. Naturally, one would expect that x is the base address (of the arrray) and y the offset/index. As the register is variable and the base address is fixed. However, electrically, the register is the base address and the fixed part of this instruction is a (signed!) offset. Which can lead to erratic behavior for data located above 0x8000. In small data model, you'd likely not getting any error message at all, but still a wrong memory location would be accessed at runtime.

    Try to rearrange your data, so your arrays fit into lower 32k of memory.

    Of course, my analysis might be wrong. I'd need to see the exact compiler-generated code (before the linker tries to relocate the addresses), and of course the source code, to be sure. MSPGCC is outputting a temporary assembly file (the compiler is not directly generating binary code) which one can inspect if the compiler is instructed to not delete it after the binary is built. This often helped me to locate the cause of error message that were unexplainable by the plain C source.

  • Thank you for the response Jens-Michael.

    Actually,the F5659 has a fairly large address space.  The issue seems to be with Sector 0.  Ram starts at offset 2400h and goes to 63FFh when in small data model.  However, it is 'mirrored' to appear above sector 3 in address space as well.  Here's the relevant part of the data sheet:

    Sector3 16KB  0FBFFFh-0F8000h
    Sector2 16KB  0F7FFFh-0F4000h
    Sector1 16KB  0F3FFFh-0F0000h
    Sector0 16KB  0063FFh–002400h (mirrored at address range 0FFFFFh-0FC000h)

    As long as all my data fits within  a 16KB block, the linker places it in memory space starting at 2400h.  If, however, our data size is greater than 16KB, the linker then correctly places data starting at 0F0000h.  And that's when I start getting the relocation errors.

    Again, I have selected large code and large data models.

    It looks as though the compiler just is not aware of 20bit mode.  Surely, I am just overlooking some additional setting.

    This is a blocker for our project.   We selected this part because we needed the large arrays to build up data which is then sent to an attached SD Card periodically.

    Any help would be greatly appreciated.

  • I see. Yes, apparently the compiler does not use large data model properly, assuming 16 bit locations for variables. Probably, large data model support is limited to access of constants in flash, and data pointers, but does not cover static variables.

    This MSP is one of very few, very new MSPs with ram above 64k. Others, with 32k ram, have all ram below 64k (and only 16k of flash or so below 64k)

    Apparently, the linker links data into lower 64k if it doesn't exceed 16k, but locates it in upper 64k when data grows larger.
    I'd say this is a bug.

    A workaround could be to dynamically allocate the storage space using malloc, and using data pointers for the access.
    Or use a fixed location for these arrays in the unmirrored ram.
    You may even initialize these arrays from flash by copying const arrays into them.
    Just keep the amount of static variables below 16k.

  • Yes.  Pointer access would seem to be a solution.

    However, I've got a several packages pulled into this project (USB, Bluetooth Stack, FatFS, FreeRTOS) that would require major overhauls to change all data access to pointer access.

    Not something that I would want to tackle.

    Do you know if TI is aware of this issue?

  • Did you try to alter your Linker Command File? Creating sections for your data and/or free the ‘.text:_isr : {} > FLASH’ from code by altering ‘.text: {}>> FLASH2 | FLASH’ (FLASH2 first).

  • Yes, I have tried several mods.  Moving .text and/or .text_isr simply changes the severity of the warnings and errors.

    It seems as though the entire issue is that if total statically allocated variables exceeds 16K, the linker just can't seem handle putting them anywhere but in the 0x2400-0x63ff area.

    Unfortunately, I have limited control over globals.  The biggest culprit is FreeRTOS.  That package manages it's own heap for task stacks, etc.  We architected this project assuming large data model gave us a flat memory space of 64KBytes.  Evidently, not so.

    Things are not looking good at this point.

    UPDATE:

    It looks as though the compiler insists on using a field type of R_MSP430X_ABS16 on any and all global variables.  Then the linker complains about not being able to place a 20-bit address in that 16-bit field.  At least, that's what it looks like to me.

    Is this a compiler settings issue?  Or a bug?

  • Maybe it helps you when you disable ‘near_data’ (none).

  • Right.  --near_data is blank in the project settings.

  • Good to hear its solved. Probably there is a way to declare variables/sections as ‘near’ or ‘far’ but I don’t know how, never searched especially for it. Anyhow it would be good if.

  • Sorry, I wasn't clear.  What I should have said is that --near_data settings did not seem to help and so I've left it blank for a while now.

    HOWEVER!

    On a whim, I tried setting -near_data=none again.  That seems to let the linker correctly place all statics starting at 0xF0000 like I want and I do not get any relocation errors.

    So, I tried running the program and !!! it works!

    All statics now begin at 0xF0000, ISRs are working, one large array of 20,000 characters is being correctly accessed.

    Not sure how I missed this, but Leo, thanks for the nudge.   I thought you meant 'blank'.  But, you are right, 'none' is the correct setting.

    Thanks to all who helped walk me through this.

**Attention** This is a public forum