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.

Z-STACK: Linker problem with data not fitting in DATA16

Other Parts Discussed in Thread: Z-STACK

Hi,

I'm running out of data memory in an MSP430F547A running Z-Stack 2.5.1 and GrLib. And compiling with IAR EW430 5.52

Everything was compiling and running fine, but we had to replace the fonts in GrLib with new ones with the full character set for ISO-8859-1 (mainly due to acute accents and the similar).

We are using 4 different sizes of fonts and we are building them with ftrasterize. The output of the tool, counting the 4 fonts, is approximately 29-30KB, which make the linker complain about data not fitting into DATA16 segments. All this data is defined as const as it won't change at all.

We have tried changing the data model to medium or large, but that's not possible with Z-Stack, as some pre-compiled modules are set up with the small data model, so we get an error as described in this old post:

http://e2e.ti.com/support/low_power_rf/f/158/t/117107.aspx

I've been trying to solve this issue for a couple of weeks and I'm running out of ideas. I've tried everything I can think of and read from the compilers manuals & forums in order to force those large constants into upper flash, but I'm restricted to the DATA16 area (i.e. <0xFFFF).

I don't see how I could use __data20_read & write instructions other than downloading the fonts over the air and writing them to upper flash, and then modifying grlib to transparently use __data20_read instructions for using the fonts, but this seems to me like an overkill for the functionality.

Any idea will be welcome, I'm sort of desperate here.... lots of memory unused in the chip and I'm running out of memory! :-(

Thanks a lot for your help.

Asier.

  • Well, you can't eat the cake and keep it. If your code or library works with small data model, you can put data only into the lower 64k. No matter how much space you have above.
    (Also, ISRs and the startup code need to be in low memory)

    If you need to store more data and do not have large data model available, all you can do is writing a copy function that fetches data from high memory (using inline assembly or compiler intrinsics) into low memory before they are passed to the library code. Difficult if the required data is 32k and your free ram is less.

    For storing the data into upper memory, you only need to tell the linker that it shall be placed there. You might want to define your own memory segments for the data, so you know where it goes to.
    You cannot directly reference the data from inside your C code by name. You'll need to know where the linekr placed it and use these values as long constants when using the compiler intrinsics. (in assembly, you can of course directly use the data names as reference, as assembly doesn't make a 'code model' chekcing - you specifiy the ASM instructions you use, and the linker will relocate the addresses properly for any 20 bit data instruction)

  • Thanks Jens-Michael,

    I was afraid that was the answer, but I was not sure about how to place data in the upper memory. I'm working with the compiler reference manual, so I guess I'll manage.

    As a first step I'm reducing the character set for trying to fit it into memory (I'm quite tight on schedule), and I will rewrite the access functions afterwards, I guess it's going to take me some time. It involves changing all related functions in the grlib font-related functions.

    There they make a thorough use of pointer, with assignments, increments and the like, so I plan to change those access for a function which retrieves each requested data from memory in "real-time" instead of copying the whole structure. But it will also required tracking positions and counters. :-(

    If anyone knows of an straight-forward way to substitute pointers operations with a function returning values, it would be a great help.

    Thanks a lot again. Best regards,

    Asier.

  • Asier Azaceta said:
    If anyone knows of an straight-forward way to substitute pointers operations with a function returning values,

    That's not really straightforward.
    It is a commonly used method to avoid passing large amounts of parameters to sub-functions. Instead, a global struct is filled with parameters and precalculated values, so that recalculations can be skipped when the prerequisites didn't change etc.
    If done properly, it makes code difficult to analyze, but smaller and way faster.

    I've once gone through it with the IJG JPG library when porting it to GEOS OS. It was a major task replacing the pointer usage by parameters and function calls (they even used function pointers for different decode sub-functions based on the JPG header analysis). GEOS did/does have an incompatible memory management to the originally used flat memory model, so the pointers didn't work.

    If you have the library sourcecode, maybe you can locate a key function where you can add copying the jut required data to low memory and keep the pointer approach, instead of rewriting everything.Well, it still requires a fairly complete analysis of the library.

  • Thanks a lot Jens-Michael for the insight. 

    I'm gonna need to put some hard work into this to get some results, I'm afraid.

    Best regards,

    Asier.

**Attention** This is a public forum