EmbeddedRelated.com
Forums

IAR: volatile const int x @ 0x1000 = 123 ;

Started by reym...@... February 14, 2006
Dear all!

Once more a problem with IAR's C-compiler.  (V3.40A)
I'm trying to place a variable in the information (flash) memory.

Sounds very simple but turns out to be complicated like hell.

My first idea was something like this:
volatile const int x @ "INFO" = 123;


I even found something very similar in the compiler reference page 35:
---------------------------<snip>-----
In the following examples, there are two const declared objects, where the
first is
initialized to zero, and the second is initialized to a specific value.
Both objects are
placed in ROM. This is useful for configuration parameters, which are
accessible from
an external interface. Note that in the second case, the compiler is not
obliged to actually
read from the variable, because the value is known. To force the compiler
to read the
value, declare it volatile:

#pragma location=0x0202
volatile const int beta; /* OK */
volatile const int gamma @ 0x0204 = 3; /* OK */
---------------------------<snip>-----


OK, let's try it...


*** volatile const int gamma @ 0x0204 = 3 ;  ***
-> Error[Be022]: location address not allowed for initialized variables
(writable variables without the __no_init attribute)

Similar results for the first example.

Actually 'const int gamma @ 0x0204 = 3;' does compile, but due to the
lack
of 'volatile' the code will never look
at that memory position again. :-(

So what?
Stupid compiler or stupid user?


regards
Dirk






Beginning Microcontrollers with the MSP430

On Tue, 14 Feb 2006 19:27:15 +0100, Dirk wrote:

>Once more a problem with IAR's C-compiler. 
(V3.40A)
>I'm trying to place a variable in the information (flash) memory.
>
>Sounds very simple but turns out to be complicated like hell.
>
>My first idea was something like this:
>volatile const int x @ "INFO" = 123;
>
>
>I even found something very similar in the compiler reference page 35:
>---------------------------<snip>-----
>In the following examples, there are two const declared objects, where the
>first is
>initialized to zero, and the second is initialized to a specific value.
>Both objects are
>placed in ROM. This is useful for configuration parameters, which are
>accessible from
>an external interface. Note that in the second case, the compiler is not
>obliged to actually
>read from the variable, because the value is known. To force the compiler
>to read the
>value, declare it volatile:
>
>#pragma location=0x0202
>volatile const int beta; /* OK */
>volatile const int gamma @ 0x0204 = 3; /* OK */
>---------------------------<snip>-----
>
>
>OK, let's try it...
>
>
>*** volatile const int gamma @ 0x0204 = 3 ;  ***
>-> Error[Be022]: location address not allowed for initialized variables
>(writable variables without the __no_init attribute)
>
>Similar results for the first example.
>
>Actually 'const int gamma @ 0x0204 = 3;' does compile, but due to
the lack
>of 'volatile' the code will never look
>at that memory position again. :-(
>
>So what?
>Stupid compiler or stupid user?

I don't use the IAR C compiler and I don't want to start, just yet. So
I'll just be thinking off the top of my head...

I notice in the IAR .h files, something like this:

: #define DEFC(name, address) __no_init volatile unsigned char name @ address;
: #define DEFW(name, address) __no_init volatile unsigned short name @ address;

(the colons are placed to keep my posting program from wrapping the
lines.)

I do _not_ find any situation where they combine volatile and const,
though.

And I have your experiences to examine, as well.

From this, and I'm guessing at some of these, there are several
possibilities.  One is that volatile and const may not be combined in
the version of C compiler you are using.  It may be perfectly valid
for C, generally, but not accepted by the compiler version.  I don't
think this is terribly likely, though, since it is reasonable to
combine these two qualifiers.  So that leaves me with another, which
is that volatile objects are not allowed to be initialized, on the
theory that if they really _are_ volatile, in that they may be
modified from outside of the vision or view of the C compiler, that it
doesn't make sense (to the compiler writer, at least) to initialize
them to any particular value within the C compiler control.  In the
case of the examples I'm finding in the .h files, where __no_init is
added, I think this is so that the compiler doesn't place them into an
initialized data segment (in C, static objects without initializers
are still initialized to a semantic zero, so they are still
initialized even if it may not seem so.  This seems very reasonable in
the case of specifying hardware registers, of course, which should not
be in any initialized data segment and since C itself doesn't provide
syntax for such a semantic, I can see why the compiler folks may have
added this.  But if so, and if you aren't talking about a hardware
register that is volatile, but some other object (which may, let's
say, be impacted by an assembly routine hooked to an interrupt), then
the __no_init qualifier may not be needed in order to avoid having
this object placed in an initialized data segment and that might mean
you _should_ be able to specify an initial value for it, despite the
fact that it is volatile.  And then there is the error message itself,
which appears to just state that the address is one where you aren't
allowed to initialize values.  This may simply be because the segment
that the variable is being placed into, by default or otherwise, is
given in the .XCL file with a -Z thing that disallows this.  But I'm
not even sure where your error arrives from, linker or compiler.

So I don't really know.  And it wouldn't surprise me that I missed
something you wrote that I should have noticed, too, and would have
cinched things for me.  But let's hear from the IAR folks, I suppose.

Jon

I had the same problem.  It's very confusing with that bit in the
userguide.
use the __root keyword instead of volatile if it's being optimized out.

This works for me:
__root const int x@0x1000 = 123;

You can make that static without a problem:
__root static const int x@0x1000 = 123;


Steve

On 2/14/06, reymannd@reym... <reymannd@reym...>
wrote:
> Dear all!
>
> Once more a problem with IAR's C-compiler.  (V3.40A)
> I'm trying to place a variable in the information (flash) memory.
>
> Sounds very simple but turns out to be complicated like hell.
>
> My first idea was something like this:
> volatile const int x @ "INFO" = 123;
>
>
> I even found something very similar in the compiler reference page 35:
> ---------------------------<snip>-----
> In the following examples, there are two const declared objects, where the
> first is
> initialized to zero, and the second is initialized to a specific value.
> Both objects are
> placed in ROM. This is useful for configuration parameters, which are
> accessible from
> an external interface. Note that in the second case, the compiler is not
> obliged to actually
> read from the variable, because the value is known. To force the compiler
> to read the
> value, declare it volatile:
>
> #pragma location=0x0202
> volatile const int beta; /* OK */
> volatile const int gamma @ 0x0204 = 3; /* OK */
> ---------------------------<snip>-----
>
>
> OK, let's try it...
>
>
> *** volatile const int gamma @ 0x0204 = 3 ;  ***
> -> Error[Be022]: location address not allowed for initialized variables
> (writable variables without the __no_init attribute)
>
> Similar results for the first example.
>
> Actually 'const int gamma @ 0x0204 = 3;' does compile, but due to
the lack
> of 'volatile' the code will never look
> at that memory position again. :-(
>
> So what?
> Stupid compiler or stupid user?
>
>
> regards
> Dirk
>
>
>
>
>
>
>
> .
>
>
> Yahoo! Groups Links
>
>
>
>
>
>
>
>