EmbeddedRelated.com
Forums

Using large memory model in IAR and MSP430F5438

Started by one00100100 July 16, 2012
I started a project several years ago using this chip and the IAR (full) IDE. It has been a very successful product for us. It originally started as a small memory model. Over the years, it has grown by adding increased capabilities (mostly adding configuration data for new situations). This growth caused me to move to the medium data model about a year ago. My memory isn't really good, but it seems that this move wasn't too painful. Recently, we added language capabilities for 5 languages which caused me to have to store large amounts of strings for display, control, and reporting functions. The strings only associated with displaying on the touchscreen are stored in the touchscreen controller's memory. The strings that need to be sent serially to printers are stored in the MSP430F5438 flash memory. Once I changed to the medium memory model, I was able to change the strings to arrays of strings, using the language number as an index into the string arrays.Thisworks fine after a lot of work. Now we want to add two more languages, which will add two more elements to each string array, eating up a considerable amount of memory. The string arrays are declared as char string1 [numberOfLanguages][numberOfCharsInString] OR char* string1[numberOfLanguages] . In most cases the keyword const is used. When I increased the value of numberOfLanguages from 5 to 6 or 7, the program fails to link, saying not enough __data16 memory. If I change the memory model in the IAR options to large memory model, the linker complains that there is not enough __data20 memory. I thought if I used the small memory model, I could only address 0xFFFFbytes of memory. I assumed if I wanted to access all 256k of memory, the large memory model should allow that without a lot of pain. Obviously I am missing something here. At this point I have hacked my code which was working for 5 languages using the medium memory model so much that I am lost. I should probably return to the 5-language medium memory model code that works and proceed -- but in what direction? Any help would be greatly appreciated.
Mike Raines

Beginning Microcontrollers with the MSP430

On Mon, 16 Jul 2012 18:10:23 -0000, Mike Raines wrote:
> I started a project several years ago using this chip and
> the IAR (full) IDE.

>

> When I increased the value of numberOfLanguages from 5 to 6
> or 7, the program fails to link, saying not enough __data16
> memory. If I change the memory model in the IAR options to
> large memory model, the linker complains that there is not
> enough __data20 memory. I thought if I used the small memory
> model, I could only address 0xFFFFbytes of memory. I assumed
> if I wanted to access all 256k of memory, the large memory
> model should allow that without a lot of pain. Obviously I
> am missing something here. At this point I have hacked my
> code which was working for 5 languages using the medium
> memory model so much that I am lost. I should probably
> return to the 5-language medium memory model code that works
> and proceed -- but in what direction? Any help would be
> greatly appreciated.

Hi, Mike. I just read this and I've only been awake for 30
minutes (odd schedule right now.) But here are my initial
reactions.

(1) You have the full version of the compiler. I don't. But I
suspect that you should be getting excellent support
responses from IAR, when you ask them. I know that one of
their employees (Anders Lindgren) writes here and is very
helpful to people who aren't paying them a nickel. So this
goes a long way in my mind that they provide good support in
general. You should definitely involve them in your question.
I believe you already know that, so this leaves me with two
possibilities: (a) you are hoping for a 'faster' response
here, or (b) you do own a full version but IAR has a support
plan you haven't kept up on and so you are no longer a
'paying customer' so that brings you back to here, perhaps.

(2) It's not uncommon for linker control files used for the
various models to require some "tinkering" to fit a
particular application. If you don't know how to read a map
file output, or don't know what a linker file is and how to
modify it, or both, you should learn right now. A lot of
information comes from various listing files, map files, and
a study of how the C/C++ compiler uses the various segments
described in the linker file to compose a final binary. You
now need to know this stuff cold. So if you haven't learned
it, start learning it now. Immediately.

(3) It's possible that your chip really cannot handle the
extra memory required. From your description, it sounds a
little like you are a 'deer in the headlights' on this,
though. You don't seem to actually _know_ if it should fit,
or not. Because if you did, you would be able to carefully
provide quantities (numbers) about how much space would be
required for all your data. You didn't provide those numbers
so I'm guessing you don't have a firm grip on them.

(4) Sometimes, it all has to do with how you are declaring
your strings and other data. If you declare something at
module level, like this:

int x= 5;

The compiler knows that you might later on write:

x= 7;

So it is forced to place 'x' in ram (or something that is
writable.) Even if you never write to it. But ram comes up as
"random data" on reset. So how does the '5' get placed there
before main() starts? The compiler is also then forced to
place a '5' somewhere in flash (or persistent) memory and
then move that into the ram before calling main(). You need
to be FULLY AWARE of these requirements, especially when you
are pressuring limitations like it sounds you are. It may be
better to declare:

const int x= 5;

Or just use:

#define X (5)

But you can't be sure which is better unless you know what
kind of code is generated. Or what segments are available for
various uses by the compiler, how large they are, what
specific ones are generating your failure to compile in your
specific case, and why.... etc.

In short, you need to THINK about your situation very
closely, right now.

String arrays may be declared as:

char *s[]= { "S1", "S2", "S3" };

For an example. How do you think the compiler reads that?

It says to itself, "s is an array of writable pointers to a
writable char or array of chars." This may not be what you
want, at all. The compiler may then be forced to place copies
of the three strings into flash (because it must initialize
them) but then provide room in ram because you can write onto
them, too. So you are sucking up memory in both places, flash
and ram. There is more, as that isn't the worst yet. Not only
that, but s is an array of writable pointers. So the pointers
ALSO need to be initialized (more flash) but also writable
(more ram.)

A better way to write it might be:

const char * const s[]= { "S1", "S2", "S3" };

This tells the compiler: "s is an array of constant pointers
to a constant char or array of constant chars." Now,
everything can go into flash. Maybe. If the compiler does
that for you, automatically (probably.) Including the
pointers AND the strings, too. No ram has to be used.

So what are you doing???

Jon
Jon,
Thanks for the reply. You are right-on with your assessment of IAR support. I bumped the request up the line a bit and received some helpful responses right away. It turns out the person who originally got my request is not at all familiar with the memory models and neglected to ask for help. Also, there is an element of "deer in the headlights" here. IAR has recommended I stay with the medium memory model. I will start with your suggestions of
const char * const s[]= { "S1", "S2", "S3" };

and use the __DATA20 keyword to place them in upper memory.

Thanks again,
Mike Raines

________________________________
From: m... [mailto:m...] On Behalf Of Jon Kirwan
Sent: Monday, July 16, 2012 4:15 PM
To: MSP430 List
Subject: Re: [msp430] Using large memory model in IAR and MSP430F5438

On Mon, 16 Jul 2012 18:10:23 -0000, Mike Raines wrote:
> I started a project several years ago using this chip and
> the IAR (full) IDE.

>

> When I increased the value of numberOfLanguages from 5 to 6
> or 7, the program fails to link, saying not enough __data16
> memory. If I change the memory model in the IAR options to
> large memory model, the linker complains that there is not
> enough __data20 memory. I thought if I used the small memory
> model, I could only address 0xFFFFbytes of memory. I assumed
> if I wanted to access all 256k of memory, the large memory
> model should allow that without a lot of pain. Obviously I
> am missing something here. At this point I have hacked my
> code which was working for 5 languages using the medium
> memory model so much that I am lost. I should probably
> return to the 5-language medium memory model code that works
> and proceed -- but in what direction? Any help would be
> greatly appreciated.

Hi, Mike. I just read this and I've only been awake for 30
minutes (odd schedule right now.) But here are my initial
reactions.

(1) You have the full version of the compiler. I don't. But I
suspect that you should be getting excellent support
responses from IAR, when you ask them. I know that one of
their employees (Anders Lindgren) writes here and is very
helpful to people who aren't paying them a nickel. So this
goes a long way in my mind that they provide good support in
general. You should definitely involve them in your question.
I believe you already know that, so this leaves me with two
possibilities: (a) you are hoping for a 'faster' response
here, or (b) you do own a full version but IAR has a support
plan you haven't kept up on and so you are no longer a
'paying customer' so that brings you back to here, perhaps.

(2) It's not uncommon for linker control files used for the
various models to require some "tinkering" to fit a
particular application. If you don't know how to read a map
file output, or don't know what a linker file is and how to
modify it, or both, you should learn right now. A lot of
information comes from various listing files, map files, and
a study of how the C/C++ compiler uses the various segments
described in the linker file to compose a final binary. You
now need to know this stuff cold. So if you haven't learned
it, start learning it now. Immediately.

(3) It's possible that your chip really cannot handle the
extra memory required. From your description, it sounds a
little like you are a 'deer in the headlights' on this,
though. You don't seem to actually _know_ if it should fit,
or not. Because if you did, you would be able to carefully
provide quantities (numbers) about how much space would be
required for all your data. You didn't provide those numbers
so I'm guessing you don't have a firm grip on them.

(4) Sometimes, it all has to do with how you are declaring
your strings and other data. If you declare something at
module level, like this:

int x= 5;

The compiler knows that you might later on write:

x= 7;

So it is forced to place 'x' in ram (or something that is
writable.) Even if you never write to it. But ram comes up as
"random data" on reset. So how does the '5' get placed there
before main() starts? The compiler is also then forced to
place a '5' somewhere in flash (or persistent) memory and
then move that into the ram before calling main(). You need
to be FULLY AWARE of these requirements, especially when you
are pressuring limitations like it sounds you are. It may be
better to declare:

const int x= 5;

Or just use:

#define X (5)

But you can't be sure which is better unless you know what
kind of code is generated. Or what segments are available for
various uses by the compiler, how large they are, what
specific ones are generating your failure to compile in your
specific case, and why.... etc.

In short, you need to THINK about your situation very
closely, right now.

String arrays may be declared as:

char *s[]= { "S1", "S2", "S3" };

For an example. How do you think the compiler reads that?

It says to itself, "s is an array of writable pointers to a
writable char or array of chars." This may not be what you
want, at all. The compiler may then be forced to place copies
of the three strings into flash (because it must initialize
them) but then provide room in ram because you can write onto
them, too. So you are sucking up memory in both places, flash
and ram. There is more, as that isn't the worst yet. Not only
that, but s is an array of writable pointers. So the pointers
ALSO need to be initialized (more flash) but also writable
(more ram.)

A better way to write it might be:

const char * const s[]= { "S1", "S2", "S3" };

This tells the compiler: "s is an array of constant pointers
to a constant char or array of constant chars." Now,
everything can go into flash. Maybe. If the compiler does
that for you, automatically (probably.) Including the
pointers AND the strings, too. No ram has to be used.

So what are you doing???

Jon



I've. Been awake for too long now so... :)
You say your array is setup as a single "var"? You may get this error if the array does not fit fully in the extended memory or your code and array does not fit in normal (16 bit) memory. Try breaking the array up into smaller pieces and see if that helps. You can still use your index trick by using a list of pointers to the strings.
--- In m..., "one00100100" wrote:
>
> I started a project several years ago using this chip and the IAR (full) IDE. It has been a very successful product for us. It originally started as a small memory model. Over the years, it has grown by adding increased capabilities (mostly adding configuration data for new situations). This growth caused me to move to the medium data model about a year ago. My memory isn't really good, but it seems that this move wasn't too painful. Recently, we added language capabilities for 5 languages which caused me to have to store large amounts of strings for display, control, and reporting functions. The strings only associated with displaying on the touchscreen are stored in the touchscreen controller's memory. The strings that need to be sent serially to printers are stored in the MSP430F5438 flash memory. Once I changed to the medium memory model, I was able to change the strings to arrays of strings, using the language number as an index into the string arrays.Thisworks fine after a lot of work. Now we want to add two more languages, which will add two more elements to each string array, eating up a considerable amount of memory. The string arrays are declared as char string1 [numberOfLanguages][numberOfCharsInString] OR char* string1[numberOfLanguages] . In most cases the keyword const is used. When I increased the value of numberOfLanguages from 5 to 6 or 7, the program fails to link, saying not enough __data16 memory. If I change the memory model in the IAR options to large memory model, the linker complains that there is not enough __data20 memory. I thought if I used the small memory model, I could only address 0xFFFFbytes of memory. I assumed if I wanted to access all 256k of memory, the large memory model should allow that without a lot of pain. Obviously I am missing something here. At this point I have hacked my code which was working for 5 languages using the medium memory model so much that I am lost. I should probably return to the 5-language medium memory model code that works and proceed -- but in what direction? Any help would be greatly appreciated.
> Mike Raines
>

Agreed.. I have a project that has ALOT of text (multiple menus and languages), I just use an array of pointers and declare each seperate "menu" as a unique constant. and index into it..
 
>________________________________
>From: masman2k
>To: m...
>Sent: Friday, July 20, 2012 9:14 PM
>Subject: [msp430] Re: Using large memory model in IAR and MSP430F5438

>I've. Been awake for too long now so... :)
>You say your array is setup as a single "var"? You may get this error if the array does not fit fully in the extended memory or your code and array does not fit in normal (16 bit) memory. Try breaking the array up into smaller pieces and see if that helps. You can still use your index trick by using a list of pointers to the strings.
>
>--- In mailto:msp430%40yahoogroups.com, "one00100100" wrote:
>>
>> I started a project several years ago using this chip and the IAR (full) IDE. It has been a very successful product for us. It originally started as a small memory model. Over the years, it has grown by adding increased capabilities (mostly adding configuration data for new situations). This growth caused me to move to the medium data model about a year ago. My memory isn't really good, but it seems that this move wasn't too painful. Recently, we added language capabilities for 5 languages which caused me to have to store large amounts of strings for display, control, and reporting functions. The strings only associated with displaying on the touchscreen are stored in the touchscreen controller's memory. The strings that need to be sent serially to printers are stored in the MSP430F5438 flash memory. Once I changed to the medium memory model, I was able to change the strings to arrays of strings, using the language number as an index into the string
arrays.Thisworks fine after a lot of work. Now we want to add two more languages, which will add two more elements to each string array, eating up a considerable amount of memory. The string arrays are declared as char string1 [numberOfLanguages][numberOfCharsInString] OR char* string1[numberOfLanguages] . In most cases the keyword const is used. When I increased the value of numberOfLanguages from 5 to 6 or 7, the program fails to link, saying not enough __data16 memory. If I change the memory model in the IAR options to large memory model, the linker complains that there is not enough __data20 memory. I thought if I used the small memory model, I could only address 0xFFFFbytes of memory. I assumed if I wanted to access all 256k of memory, the large memory model should allow that without a lot of pain. Obviously I am missing something here. At this point I have hacked my code which was working for 5 languages using the medium memory model so much that
I am lost. I should probably return to the 5-language medium memory model code that works and proceed -- but in what direction? Any help would be greatly appreciated.
>> Mike Raines
>