Forums

IAR C-compiler for AVR: Array of pointers to strings in flash

Started by Erik Cato February 3, 2004
Hi group!

Looking for help from someone with experience with IAR�s C-compiler
for AVR (ATmega16/32)

I want to declare an array with pointers to constant text. And both of
the should be in flash-memory, like this.

__flash char * __flash textTab[] =
{
"Text1",
"Text2",
"Text3",
"Text4",
"Text5",
"Text6",
"Text7",
"Text8",
"Text9",
};

The array is easy to make in flash but the strings i cant manage.
I managed to accomplish it by doing like this:

__flash char textText1[] = "Text1";
__flash char textText2[] = "Text2";
__flash char textText3[] = "Text3";
__flash char textText4[] = "Text4";
__flash char textText5[] = "Text5";
__flash char textText6[] = "Text6";
__flash char textText7[] = "Text7";
__flash char textText8[] = "Text8";
__flash char textText9[] = "Text9";

__flash unsigned char __flash *textTable[] =
{
textText1,
textText2,
textText3,
textText4,
textText5,
textText6,
textText7,
textText8,
textText9,
};

But this is not sufficient bacause we need a LOT more texts.

Anyone got any idea?

//Erik
"Erik Cato" <erik.cato@japro.se> wrote in message
news:92382512.0402030328.3a419bf6@posting.google.com...
> __flash char textText1[] = "Text1"; > __flash char textText2[] = "Text2"; > __flash char textText3[] = "Text3"; > __flash char textText4[] = "Text4"; > __flash char textText5[] = "Text5"; > __flash char textText6[] = "Text6"; > __flash char textText7[] = "Text7"; > __flash char textText8[] = "Text8"; > __flash char textText9[] = "Text9"; > > __flash unsigned char __flash *textTable[] = > { > textText1, > textText2, > textText3, > textText4, > textText5, > textText6, > textText7, > textText8, > textText9, > }; > > But this is not sufficient bacause we need a LOT more texts.
AFAIK this is the only way. IAR does it this way, ICCAVR too. Meindert
erik.cato@japro.se (Erik Cato) wrote in
news:92382512.0402030328.3a419bf6@posting.google.com: 

> Hi group! > > Looking for help from someone with experience with IAR&#2013266100;s C-compiler > for AVR (ATmega16/32) > > I want to declare an array with pointers to constant text. And both of > the should be in flash-memory, like this. > > __flash char * __flash textTab[] = > { > "Text1", > "Text2", > "Text3", > "Text4", > "Text5", > "Text6", > "Text7", > "Text8", > "Text9", > };
Doesn't const help here? I may have the second const in the wrong position. const char * const textTab[] = { "foo", "bar", "baz" }; -- - Mark -> --
Erik Cato <erik.cato@japro.se> wrote:
> Looking for help from someone with experience with IAR?s C-compiler > for AVR (ATmega16/32)
> I want to declare an array with pointers to constant text. And both of > the should be in flash-memory, like this.
> __flash char * __flash textTab[] = > { > "Text1", > "Text2", > "Text3", > "Text4", > "Text5", > "Text6", > "Text7", > "Text8", > "Text9", > };
You forgot to say how this approach failed. This may just be a bug in that compiler's C extension keyword __flash, particularly in how it's parsed, or you may be missing something on how it's supposed to be used. If you've seen the trouble people have in getting the usage of standard keyword "const" right in such multi-level pointer situations, you'll realize that getting this __flash thingy to parse exactly right may be tricky. You may have to expend a couple of parens, or a typedef, like this: typedef __flash const char flashstring[]; __flash *flashstring = { /* ... */ }; -- Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.
"Hans-Bernhard Broeker" <broeker@physik.rwth-aachen.de> wrote in message
news:bvoebs$abg$1@nets3.rz.RWTH-Aachen.DE...
> > You forgot to say how this approach failed.
If you only define the array itself as const, and not the strings, only the array with pointers will be in rom or flash. The pointers are pointers to ram locations, where the strings are copied to from rom by the startup code. Meindert
erik.cato@japro.se (Erik Cato) writes:

> Hi group! > > Looking for help from someone with experience with IAR&#2013266100;s C-compiler > for AVR (ATmega16/32) > > I want to declare an array with pointers to constant text. And both of > the should be in flash-memory, like this. > > __flash char * __flash textTab[] = > { > "Text1", > "Text2", > "Text3", > "Text4", > "Text5", > "Text6", > "Text7", > "Text8", > "Text9", > };
[snipped code placing char arrays explicitly in flash memory]
> But this is not sufficient bacause we need a LOT more texts.
If you want to place string literals in flash memory, supply the command-line option --string_literals_in_flash to the compiler. But beware: it might not really solve your problem. What are you going to do with all the strings? If you are going to write them out, you will have to recompile (parts of) the library to get a printf() version accepting pointers into flash memory. Best wishes, Mats Kindahl -- IAR Systems in Uppsala, Sweden. Any opinions expressed are my own and not those of my company. Spam prevention: contact me at mNaOtSkPiAnM@acm.org or mNaOtSs.kPindAahMl@iar.se, removing the *NO SPAM* from the address.
Hans-Bernhard Broeker <broeker@physik.rwth-aachen.de> writes:

> Erik Cato <erik.cato@japro.se> wrote: > > Looking for help from someone with experience with IAR?s C-compiler > > for AVR (ATmega16/32) > > > I want to declare an array with pointers to constant text. And both of > > the should be in flash-memory, like this. > > > __flash char * __flash textTab[] = > > { > > "Text1", > > "Text2", > > "Text3", > > "Text4", > > "Text5", > > "Text6", > > "Text7", > > "Text8", > > "Text9", > > }; > > You forgot to say how this approach failed. > > This may just be a bug in that compiler's C extension keyword __flash, > particularly in how it's parsed, or you may be missing something on > how it's supposed to be used.
There's a bug in the declaration, it should write: char __flash * __flash textTab[] = .... or __flash char __flash * textTab[] = ... (I know, this is really confusing.) The reason is that writing a memory attribute first on the line associates this memory attribute to every variable being declared (for pre-ANSI backward compatability reasons). The warning message emitted is something about "char const *" not being convertible to "char __flash *" (not very surprising, they are in completely different address spaces). The problem is a result of the fact that, according to the ANSI standard, generic pointers have to be able to point to string literals and generic pointers cannot point to flash memory. Best wishes, Mats Kindahl -- IAR Systems in Uppsala, Sweden. Any opinions expressed are my own and not those of my company. Spam prevention: contact me at mNaOtSkPiAnM@acm.org or mNaOtSs.kPindAahMl@iar.se, removing the *NO SPAM* from the address.
"Meindert Sprang" <mhsprang@NOcustomSPAMware.nl> wrote in message news:<401f8a06$1@news.nb.nu>...
> "Erik Cato" <erik.cato@japro.se> wrote in message > news:92382512.0402030328.3a419bf6@posting.google.com... > > __flash char textText1[] = "Text1"; > > __flash char textText2[] = "Text2"; > > __flash char textText3[] = "Text3"; > > __flash char textText4[] = "Text4"; > > __flash char textText5[] = "Text5"; > > __flash char textText6[] = "Text6"; > > __flash char textText7[] = "Text7"; > > __flash char textText8[] = "Text8"; > > __flash char textText9[] = "Text9"; > > > > __flash unsigned char __flash *textTable[] = > > { > > textText1, > > textText2, > > textText3, > > textText4, > > textText5, > > textText6, > > textText7, > > textText8, > > textText9, > > }; > > > > But this is not sufficient bacause we need a LOT more texts. > > AFAIK this is the only way. IAR does it this way, ICCAVR too. > > Meindert
Thanks for the answer although it was incorrect! I lookad at some tech. notes at iar.com and found out that you can this with the command line option --string_literals_in_flash //Erik
Mats Kindahl <mats.kindahl@nowhere.net> wrote:

> The problem is a result of the fact that, according to the ANSI > standard, generic pointers have to be able to point to string literals > and generic pointers cannot point to flash memory.
Let's first note that ANSI/ISO C specs obviously say nothing about flash memory. Now, if the compiler does implement an extension like this __flash, but does not also implement generic pointers in a way that they *can* point at it, that's IMHO at least a serious misfeature of the compiler. It's not strictly a bug for the only reason that this whole issue is outside the domain of the standard, i.e. the implementor can technically do whatever they please about it. Such a situation effectively means that "pointers to flash" are not actually "pointers" (as defined by the language) at all. Just about every usage of such pointers could go fatally wrong, then, for lots of crazy, hard-to-find reasons. The language specs go to quite some length to make sure that generic pointers can be implemented including a "memory class specifier", if the target platform needs that. Not making use of that flexibility is somewhat wasteful. -- Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.

Hans-Bernhard Broeker wrote:

> .... > The language specs go to quite some length to make sure that generic > pointers can be implemented including a "memory class specifier", if > the target platform needs that. Not making use of that flexibility is > somewhat wasteful. >
Let me guess, you have never written a compiler for the embedded market for use by embedded engineers? :-) With all due respect, having the flexibility by the standard is nice. However, implementing a generic pointer requires the pointer to be larger than 16 bits, and runtime check to see what type of a pointer it is, thus blowing up resulting code's FLASH and RAM requirements and make things run slower. -- // richard http://www.imagecraft.com