EmbeddedRelated.com
Forums

Accesing Data on Flash

Started by gab0ar June 11, 2008
Hello, I had a problem when upgrading from IAR 3.20 to 3.42.

Some time ago I needed to declare an initialized variable on a fixed
location on flash. This variable would change on execution time, and
the value would be reffered from other parts of the code. I found the
following to work:

Declare on a .h

#define DEFAULT_VALUE 8
#define MY_LOCATION 0xF000

extern volatile const tMyVar myVar @ MY_LOCATION = {
DEFAULT_VALUE
}

And when referencing that variable from other places:

a = myVar;

Generated the following Assembly output:

MOV.B &0xfa00, 0(R12)

On version 3.42 the "volatile const" directive is not permitted
anymore so I deleted the volatile:
#define DEFAULT_VALUE 8
#define MY_LOCATION 0xF000

extern const tMyVar myVar @ MY_LOCATION = {
DEFAULT_VALUE
}

But when I reference from other parts of the code I get the following

a = myVar;

generates:

MOV.B #0x8, R14

This copies the Default value to "a" instead of the content of the
direction.

I would like to know how to make the code behave like it did on 3.2.

Its important to point that this is only an example, in my project
tMyVar is a large structure, and that I make multiple calls along
different CPP files and this CPP are always Optimized for SIZE on HIGH
(maximum optimization).

I hope I made myself clear, thanks in advance for your help.

Beginning Microcontrollers with the MSP430

Your problem is precisely that you deleted 'volatile' instead of
deleting 'const'.
It might not be the best source, but according to what I read from
http://en.wikipedia.org/wiki/Constant_%28computer_science%29#Constants
, 'const' means the variable's value is never changed which is about
as opposite as it can be to 'volatile', thus the term 'volatile const'
is a contradiction and has correctly been prohibited.

What did you expect to accomplish declaring the variable as 'const'?

Michael K.

--- In m..., "gab0ar" wrote:
>
> Hello, I had a problem when upgrading from IAR 3.20 to 3.42.
>
> Some time ago I needed to declare an initialized variable on a fixed
> location on flash. This variable would change on execution time, and
> the value would be reffered from other parts of the code. I found the
> following to work:
>
> Declare on a .h
>
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern volatile const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> And when referencing that variable from other places:
>
> a = myVar;
>
> Generated the following Assembly output:
>
> MOV.B &0xfa00, 0(R12)
>
>
> On version 3.42 the "volatile const" directive is not permitted
> anymore so I deleted the volatile:
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> But when I reference from other parts of the code I get the following
>
> a = myVar;
>
> generates:
>
> MOV.B #0x8, R14
>
> This copies the Default value to "a" instead of the content of the
> direction.
>
> I would like to know how to make the code behave like it did on 3.2.
>
> Its important to point that this is only an example, in my project
> tMyVar is a large structure, and that I make multiple calls along
> different CPP files and this CPP are always Optimized for SIZE on HIGH
> (maximum optimization).
>
> I hope I made myself clear, thanks in advance for your help.
>

My guess is that you're using const because the value is located in flash rather than RAM.
It seems obvious that your problem is being caused by the optimization engine.
Here is what I'd suggest.

instead of doing this:
a = myVar;

try doing this:
a = *(tMyVar*)(&myVar);

Technically, they should be equivalent, but it might force the optimizer into doing what you want instead of removing the memory reference and replacing it with the default value.

Aaron

----- Original Message -----
From: "gab0ar"
To: m...
Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
Subject: [msp430] Accesing Data on Flash

Hello, I had a problem when upgrading from IAR 3.20 to 3.42.

Some time ago I needed to declare an initialized variable on a fixed
location on flash. This variable would change on execution time, and
the value would be reffered from other parts of the code. I found the
following to work:

Declare on a .h

#define DEFAULT_VALUE 8
#define MY_LOCATION 0xF000

extern volatile const tMyVar myVar @ MY_LOCATION = {
DEFAULT_VALUE
}

And when referencing that variable from other places:

a = myVar;

Generated the following Assembly output:

MOV.B &0xfa00, 0(R12)
On version 3.42 the "volatile const" directive is not permitted
anymore so I deleted the volatile:

#define DEFAULT_VALUE 8
#define MY_LOCATION 0xF000

extern const tMyVar myVar @ MY_LOCATION = {
DEFAULT_VALUE
}

But when I reference from other parts of the code I get the following

a = myVar;

generates:

MOV.B #0x8, R14

This copies the Default value to "a" instead of the content of the
direction.

I would like to know how to make the code behave like it did on 3.2.

Its important to point that this is only an example, in my project
tMyVar is a large structure, and that I make multiple calls along
different CPP files and this CPP are always Optimized for SIZE on HIGH
(maximum optimization).

I hope I made myself clear, thanks in advance for your help.


Here is something else you might try:
__root const tMyVar myVar @ MY_LOCATION = {DEFAULT_VALUE};

>From EW430 Compiler Reference:
__root Ensures that a function or variable is included in the object code even if unused
Aaron
----- Original Message -----
From: "gab0ar"
To: m...
Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
Subject: [msp430] Accesing Data on Flash

Hello, I had a problem when upgrading from IAR 3.20 to 3.42.

Some time ago I needed to declare an initialized variable on a fixed
location on flash. This variable would change on execution time, and
the value would be reffered from other parts of the code. I found the
following to work:

Declare on a .h

#define DEFAULT_VALUE 8
#define MY_LOCATION 0xF000

extern volatile const tMyVar myVar @ MY_LOCATION = {
DEFAULT_VALUE
}

And when referencing that variable from other places:

a = myVar;

Generated the following Assembly output:

MOV.B &0xfa00, 0(R12)
On version 3.42 the "volatile const" directive is not permitted
anymore so I deleted the volatile:

#define DEFAULT_VALUE 8
#define MY_LOCATION 0xF000

extern const tMyVar myVar @ MY_LOCATION = {
DEFAULT_VALUE
}

But when I reference from other parts of the code I get the following

a = myVar;

generates:

MOV.B #0x8, R14

This copies the Default value to "a" instead of the content of the
direction.

I would like to know how to make the code behave like it did on 3.2.

Its important to point that this is only an example, in my project
tMyVar is a large structure, and that I make multiple calls along
different CPP files and this CPP are always Optimized for SIZE on HIGH
(maximum optimization).

I hope I made myself clear, thanks in advance for your help.


Thanks for answering.

Your guess is right, i need this variable in FLASH, in fact i need it
to be specifically on the location MY_VAR which is the start of a
FLASH page (which in time i will erase and write the new values).

According to IAR documentation the @ operator used to locate variables
at fixed addresses can only be use with "const" o "no init". As I
need this variables to have some initial values the "__no_init" is
discarded, so the "const" is a must.
On the other hand, i need to tell the compiler that the value of that
variable may change between different access (when i change the flash
on execution time), so it needs to read the values instead of the
default data.
I quote this from the IAR documentation (page 35 MSP430 C/C++ IAR
Compiler: Reference Guide):

"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 */"

Since that seemed to be the exact solution to my problem, i used the
last example (volatile const) with no problems until the 3.42 crossed
my path.

I tried your solution

a = *(tMyVar*)(&myVar);

and it really works! But as i mentioned before in reality i have a
large structure with a lot of variables. And around 45K of code which
i dont want to search looking for all the access to such variables. Im
hoping there is another way (or trick) to tell the compiler to use
always the variable and not the value when optimizing.

Thanks again for the help.
--- In m..., Aaron Greer wrote:
>
> My guess is that you're using const because the value is located in
flash rather than RAM.
> It seems obvious that your problem is being caused by the
optimization engine.
> Here is what I'd suggest.
>
> instead of doing this:
> a = myVar;
>
> try doing this:
> a = *(tMyVar*)(&myVar);
>
> Technically, they should be equivalent, but it might force the
optimizer into doing what you want instead of removing the memory
reference and replacing it with the default value.
>
> Aaron
>
> ----- Original Message -----
> From: "gab0ar"
> To: m...
> Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
> Subject: [msp430] Accesing Data on Flash
>
> Hello, I had a problem when upgrading from IAR 3.20 to 3.42.
>
> Some time ago I needed to declare an initialized variable on a fixed
> location on flash. This variable would change on execution time, and
> the value would be reffered from other parts of the code. I found the
> following to work:
>
> Declare on a .h
>
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern volatile const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> And when referencing that variable from other places:
>
> a = myVar;
>
> Generated the following Assembly output:
>
> MOV.B &0xfa00, 0(R12)
> On version 3.42 the "volatile const" directive is not permitted
> anymore so I deleted the volatile:
>
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> But when I reference from other parts of the code I get the following
>
> a = myVar;
>
> generates:
>
> MOV.B #0x8, R14
>
> This copies the Default value to "a" instead of the content of the
> direction.
>
> I would like to know how to make the code behave like it did on 3.2.
>
> Its important to point that this is only an example, in my project
> tMyVar is a large structure, and that I make multiple calls along
> different CPP files and this CPP are always Optimized for SIZE on HIGH
> (maximum optimization).
>
> I hope I made myself clear, thanks in advance for your help.
>
>
>

Can you show the error message you are getting when declaring your variables as volatile const? It's strange that it won't work, especially when IAR has included examples using it.

Aaron

----- Original Message -----
From: "gab0ar"
To: m...
Sent: Wednesday, June 11, 2008 1:03:09 PM (GMT-0700) America/Denver
Subject: [msp430] Re: Accesing Data on Flash

Thanks for answering.

Your guess is right, i need this variable in FLASH, in fact i need it
to be specifically on the location MY_VAR which is the start of a
FLASH page (which in time i will erase and write the new values).

According to IAR documentation the @ operator used to locate variables
at fixed addresses can only be use with "const" o "no init". As I
need this variables to have some initial values the "__no_init" is
discarded, so the "const" is a must.

On the other hand, i need to tell the compiler that the value of that
variable may change between different access (when i change the flash
on execution time), so it needs to read the values instead of the
default data.
I quote this from the IAR documentation (page 35 MSP430 C/C++ IAR
Compiler: Reference Guide):

"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 */"

Since that seemed to be the exact solution to my problem, i used the
last example (volatile const) with no problems until the 3.42 crossed
my path.

I tried your solution

a = *(tMyVar*)(&myVar);

and it really works! But as i mentioned before in reality i have a
large structure with a lot of variables. And around 45K of code which
i dont want to search looking for all the access to such variables. Im
hoping there is another way (or trick) to tell the compiler to use
always the variable and not the value when optimizing.

Thanks again for the help.

--- In m... , Aaron Greer wrote:
>
> My guess is that you're using const because the value is located in
flash rather than RAM.
> It seems obvious that your problem is being caused by the
optimization engine.
> Here is what I'd suggest.
>
> instead of doing this:
> a = myVar;
>
> try doing this:
> a = *(tMyVar*)(&myVar);
>
> Technically, they should be equivalent, but it might force the
optimizer into doing what you want instead of removing the memory
reference and replacing it with the default value.
>
> Aaron
>
> ----- Original Message -----
> From: "gab0ar"
> To: m...
> Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
> Subject: [msp430] Accesing Data on Flash
>
> Hello, I had a problem when upgrading from IAR 3.20 to 3.42.
>
> Some time ago I needed to declare an initialized variable on a fixed
> location on flash. This variable would change on execution time, and
> the value would be reffered from other parts of the code. I found the
> following to work:
>
> Declare on a .h
>
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern volatile const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> And when referencing that variable from other places:
>
> a = myVar;
>
> Generated the following Assembly output:
>
> MOV.B &0xfa00, 0(R12)
> On version 3.42 the "volatile const" directive is not permitted
> anymore so I deleted the volatile:
>
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> But when I reference from other parts of the code I get the following
>
> a = myVar;
>
> generates:
>
> MOV.B #0x8, R14
>
> This copies the Default value to "a" instead of the content of the
> direction.
>
> I would like to know how to make the code behave like it did on 3.2.
>
> Its important to point that this is only an example, in my project
> tMyVar is a large structure, and that I make multiple calls along
> different CPP files and this CPP are always Optimized for SIZE on HIGH
> (maximum optimization).
>
> I hope I made myself clear, thanks in advance for your help.
>
>
>


I've been trying a few things with IAR, and I am also unable to make their examples work.

Here is the error I get when declaring a global such as:
volatile const int gamma @ 0x0204 = 3;
Error[Be022]: location address not allowed for initialized variables (writable variables without the __no_init attribute)

So, I came up with something that will probably work for you. It only requires two changes to the variable declarations and the addition of a macro (for each variable).

Before:
const int gamma @ 0x0204 = 3;
int main(void){
int t = gamma; // compiles to MOV.W #0x3, &t
}

After :
_root const int _gamma @ 0x0204 = 3;
#define gamma (*(int*)(0x0204))
int main(void){
int t = gamma; // compiles to MOV.W &0x204, &t
}

I know it's not the cleanest workaround in the world, especially for a large number of variables, but it does work and doesn't require you to modify the code at all the access points.

Aaron

----- Original Message -----
From: "gab0ar"
To: m...
Sent: Wednesday, June 11, 2008 1:03:09 PM (GMT-0700) America/Denver
Subject: [msp430] Re: Accesing Data on Flash

Thanks for answering.

Your guess is right, i need this variable in FLASH, in fact i need it
to be specifically on the location MY_VAR which is the start of a
FLASH page (which in time i will erase and write the new values).

According to IAR documentation the @ operator used to locate variables
at fixed addresses can only be use with "const" o "no init". As I
need this variables to have some initial values the "__no_init" is
discarded, so the "const" is a must.

On the other hand, i need to tell the compiler that the value of that
variable may change between different access (when i change the flash
on execution time), so it needs to read the values instead of the
default data.
I quote this from the IAR documentation (page 35 MSP430 C/C++ IAR
Compiler: Reference Guide):

"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 */"

Since that seemed to be the exact solution to my problem, i used the
last example (volatile const) with no problems until the 3.42 crossed
my path.

I tried your solution

a = *(tMyVar*)(&myVar);

and it really works! But as i mentioned before in reality i have a
large structure with a lot of variables. And around 45K of code which
i dont want to search looking for all the access to such variables. Im
hoping there is another way (or trick) to tell the compiler to use
always the variable and not the value when optimizing.

Thanks again for the help.

--- In m... , Aaron Greer wrote:
>
> My guess is that you're using const because the value is located in
flash rather than RAM.
> It seems obvious that your problem is being caused by the
optimization engine.
> Here is what I'd suggest.
>
> instead of doing this:
> a = myVar;
>
> try doing this:
> a = *(tMyVar*)(&myVar);
>
> Technically, they should be equivalent, but it might force the
optimizer into doing what you want instead of removing the memory
reference and replacing it with the default value.
>
> Aaron
>
> ----- Original Message -----
> From: "gab0ar"
> To: m...
> Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
> Subject: [msp430] Accesing Data on Flash
>
> Hello, I had a problem when upgrading from IAR 3.20 to 3.42.
>
> Some time ago I needed to declare an initialized variable on a fixed
> location on flash. This variable would change on execution time, and
> the value would be reffered from other parts of the code. I found the
> following to work:
>
> Declare on a .h
>
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern volatile const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> And when referencing that variable from other places:
>
> a = myVar;
>
> Generated the following Assembly output:
>
> MOV.B &0xfa00, 0(R12)
> On version 3.42 the "volatile const" directive is not permitted
> anymore so I deleted the volatile:
>
> #define DEFAULT_VALUE 8
> #define MY_LOCATION 0xF000
>
> extern const tMyVar myVar @ MY_LOCATION = {
> DEFAULT_VALUE
> }
>
> But when I reference from other parts of the code I get the following
>
> a = myVar;
>
> generates:
>
> MOV.B #0x8, R14
>
> This copies the Default value to "a" instead of the content of the
> direction.
>
> I would like to know how to make the code behave like it did on 3.2.
>
> Its important to point that this is only an example, in my project
> tMyVar is a large structure, and that I make multiple calls along
> different CPP files and this CPP are always Optimized for SIZE on HIGH
> (maximum optimization).
>
> I hope I made myself clear, thanks in advance for your help.
>
>
>


I do not understand c (nor use c). But I think the statement:
"_root const int _gamma @ 0x0204 = 3;"
does not do any good.

I think it does not make "_gamma" nor "@ 0x0204" equal to 3.

You code "works" the same way with or without that statement.
That is, the variable t is initialize with the value of "@ 0x204"
which is usually not 3.

--- In m..., Aaron Greer wrote:
>
> I've been trying a few things with IAR, and I am also unable to make
their examples work.
>
> Here is the error I get when declaring a global such as:
> volatile const int gamma @ 0x0204 = 3;
> Error[Be022]: location address not allowed for initialized variables
(writable variables without the __no_init attribute)
>
> So, I came up with something that will probably work for you. It
only requires two changes to the variable declarations and the
addition of a macro (for each variable).
>
> Before:
> const int gamma @ 0x0204 = 3;
> int main(void){
> int t = gamma; // compiles to MOV.W #0x3, &t
> }
>
> After :
> _root const int _gamma @ 0x0204 = 3;
> #define gamma (*(int*)(0x0204))
> int main(void){
> int t = gamma; // compiles to MOV.W &0x204, &t
> }
>
> I know it's not the cleanest workaround in the world, especially for
a large number of variables, but it does work and doesn't require you
to modify the code at all the access points.
>
> Aaron
>
> ----- Original Message -----
> From: "gab0ar"
> To: m...
> Sent: Wednesday, June 11, 2008 1:03:09 PM (GMT-0700) America/Denver
> Subject: [msp430] Re: Accesing Data on Flash
>
> Thanks for answering.
>
> Your guess is right, i need this variable in FLASH, in fact i need it
> to be specifically on the location MY_VAR which is the start of a
> FLASH page (which in time i will erase and write the new values).
>
> According to IAR documentation the @ operator used to locate variables
> at fixed addresses can only be use with "const" o "no init". As I
> need this variables to have some initial values the "__no_init" is
> discarded, so the "const" is a must.
>
> On the other hand, i need to tell the compiler that the value of that
> variable may change between different access (when i change the flash
> on execution time), so it needs to read the values instead of the
> default data.
> I quote this from the IAR documentation (page 35 MSP430 C/C++ IAR
> Compiler: Reference Guide):
>
> "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 */"
>
> Since that seemed to be the exact solution to my problem, i used the
> last example (volatile const) with no problems until the 3.42 crossed
> my path.
>
> I tried your solution
>
> a = *(tMyVar*)(&myVar);
>
> and it really works! But as i mentioned before in reality i have a
> large structure with a lot of variables. And around 45K of code which
> i dont want to search looking for all the access to such variables. Im
> hoping there is another way (or trick) to tell the compiler to use
> always the variable and not the value when optimizing.
>
> Thanks again for the help.
>
> --- In m... , Aaron Greer wrote:
> >
> > My guess is that you're using const because the value is located in
> flash rather than RAM.
> > It seems obvious that your problem is being caused by the
> optimization engine.
> > Here is what I'd suggest.
> >
> > instead of doing this:
> > a = myVar;
> >
> > try doing this:
> > a = *(tMyVar*)(&myVar);
> >
> > Technically, they should be equivalent, but it might force the
> optimizer into doing what you want instead of removing the memory
> reference and replacing it with the default value.
> >
> > Aaron
> >
> > ----- Original Message -----
> > From: "gab0ar"
> > To: m...
> > Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
> > Subject: [msp430] Accesing Data on Flash
> >
> >
> >
> >
> >
> >
> >
> > Hello, I had a problem when upgrading from IAR 3.20 to 3.42.
> >
> > Some time ago I needed to declare an initialized variable on a fixed
> > location on flash. This variable would change on execution time, and
> > the value would be reffered from other parts of the code. I found the
> > following to work:
> >
> > Declare on a .h
> >
> > #define DEFAULT_VALUE 8
> > #define MY_LOCATION 0xF000
> >
> > extern volatile const tMyVar myVar @ MY_LOCATION = {
> > DEFAULT_VALUE
> > }
> >
> > And when referencing that variable from other places:
> >
> > a = myVar;
> >
> > Generated the following Assembly output:
> >
> > MOV.B &0xfa00, 0(R12)
> >
> >
> > On version 3.42 the "volatile const" directive is not permitted
> > anymore so I deleted the volatile:
> >
> > #define DEFAULT_VALUE 8
> > #define MY_LOCATION 0xF000
> >
> > extern const tMyVar myVar @ MY_LOCATION = {
> > DEFAULT_VALUE
> > }
> >
> > But when I reference from other parts of the code I get the following
> >
> > a = myVar;
> >
> > generates:
> >
> > MOV.B #0x8, R14
> >
> > This copies the Default value to "a" instead of the content of the
> > direction.
> >
> > I would like to know how to make the code behave like it did on 3.2.
> >
> > Its important to point that this is only an example, in my project
> > tMyVar is a large structure, and that I make multiple calls along
> > different CPP files and this CPP are always Optimized for SIZE on
HIGH
> > (maximum optimization).
> >
> > I hope I made myself clear, thanks in advance for your help.
> >
> >
> >
> >
> >
>

OCY what you fail to realize is that this is a specific tool chain issue specific to C.
Open up IAR V3.42 and give it a try, you'll see what I'm talking about.

----- Original Message -----
From: "old_cow_yellow"
To: m...
Sent: Wednesday, June 11, 2008 3:15:07 PM (GMT-0700) America/Denver
Subject: [msp430] Re: Accesing Data on Flash

I do not understand c (nor use c). But I think the statement:
"_root const int _gamma @ 0x0204 = 3;"
does not do any good.

I think it does not make "_gamma" nor "@ 0x0204" equal to 3.

You code "works" the same way with or without that statement.
That is, the variable t is initialize with the value of "@ 0x204"
which is usually not 3.

--- In m... , Aaron Greer wrote:
>
> I've been trying a few things with IAR, and I am also unable to make
their examples work.
>
> Here is the error I get when declaring a global such as:
> volatile const int gamma @ 0x0204 = 3;
> Error[Be022]: location address not allowed for initialized variables
(writable variables without the __no_init attribute)
>
> So, I came up with something that will probably work for you. It
only requires two changes to the variable declarations and the
addition of a macro (for each variable).
>
> Before:
> const int gamma @ 0x0204 = 3;
> int main(void){
> int t = gamma; // compiles to MOV.W #0x3, &t
> }
>
> After :
> _root const int _gamma @ 0x0204 = 3;
> #define gamma (*(int*)(0x0204))
> int main(void){
> int t = gamma; // compiles to MOV.W &0x204, &t
> }
>
> I know it's not the cleanest workaround in the world, especially for
a large number of variables, but it does work and doesn't require you
to modify the code at all the access points.
>
> Aaron
>
> ----- Original Message -----
> From: "gab0ar"
> To: m...
> Sent: Wednesday, June 11, 2008 1:03:09 PM (GMT-0700) America/Denver
> Subject: [msp430] Re: Accesing Data on Flash
>
> Thanks for answering.
>
> Your guess is right, i need this variable in FLASH, in fact i need it
> to be specifically on the location MY_VAR which is the start of a
> FLASH page (which in time i will erase and write the new values).
>
> According to IAR documentation the @ operator used to locate variables
> at fixed addresses can only be use with "const" o "no init". As I
> need this variables to have some initial values the "__no_init" is
> discarded, so the "const" is a must.
>
> On the other hand, i need to tell the compiler that the value of that
> variable may change between different access (when i change the flash
> on execution time), so it needs to read the values instead of the
> default data.
> I quote this from the IAR documentation (page 35 MSP430 C/C++ IAR
> Compiler: Reference Guide):
>
> "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 */"
>
> Since that seemed to be the exact solution to my problem, i used the
> last example (volatile const) with no problems until the 3.42 crossed
> my path.
>
> I tried your solution
>
> a = *(tMyVar*)(&myVar);
>
> and it really works! But as i mentioned before in reality i have a
> large structure with a lot of variables. And around 45K of code which
> i dont want to search looking for all the access to such variables. Im
> hoping there is another way (or trick) to tell the compiler to use
> always the variable and not the value when optimizing.
>
> Thanks again for the help.
>
> --- In m... , Aaron Greer wrote:
> >
> > My guess is that you're using const because the value is located in
> flash rather than RAM.
> > It seems obvious that your problem is being caused by the
> optimization engine.
> > Here is what I'd suggest.
> >
> > instead of doing this:
> > a = myVar;
> >
> > try doing this:
> > a = *(tMyVar*)(&myVar);
> >
> > Technically, they should be equivalent, but it might force the
> optimizer into doing what you want instead of removing the memory
> reference and replacing it with the default value.
> >
> > Aaron
> >
> > ----- Original Message -----
> > From: "gab0ar"
> > To: m...
> > Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
> > Subject: [msp430] Accesing Data on Flash
> >
> >
> >
> >
> >
> >
> >
> > Hello, I had a problem when upgrading from IAR 3.20 to 3.42.
> >
> > Some time ago I needed to declare an initialized variable on a fixed
> > location on flash. This variable would change on execution time, and
> > the value would be reffered from other parts of the code. I found the
> > following to work:
> >
> > Declare on a .h
> >
> > #define DEFAULT_VALUE 8
> > #define MY_LOCATION 0xF000
> >
> > extern volatile const tMyVar myVar @ MY_LOCATION = {
> > DEFAULT_VALUE
> > }
> >
> > And when referencing that variable from other places:
> >
> > a = myVar;
> >
> > Generated the following Assembly output:
> >
> > MOV.B &0xfa00, 0(R12)
> >
> >
> > On version 3.42 the "volatile const" directive is not permitted
> > anymore so I deleted the volatile:
> >
> > #define DEFAULT_VALUE 8
> > #define MY_LOCATION 0xF000
> >
> > extern const tMyVar myVar @ MY_LOCATION = {
> > DEFAULT_VALUE
> > }
> >
> > But when I reference from other parts of the code I get the following
> >
> > a = myVar;
> >
> > generates:
> >
> > MOV.B #0x8, R14
> >
> > This copies the Default value to "a" instead of the content of the
> > direction.
> >
> > I would like to know how to make the code behave like it did on 3.2.
> >
> > Its important to point that this is only an example, in my project
> > tMyVar is a large structure, and that I make multiple calls along
> > different CPP files and this CPP are always Optimized for SIZE on
HIGH
> > (maximum optimization).
> >
> > I hope I made myself clear, thanks in advance for your help.
> >
> >
> >
> >
> >
>


Sorry. I tried with IAR V3.42A and did not notice the "A".
For V3.42A,

const int _gamma @ 0x0204 = 3;
#define gamma (*(int*)(0x0204))
int main(void)
{
int t = gamma; // compiles to MOV.W &0x204, &t
return t;
}

and

// const int _gamma @ 0x0204 = 3;
#define gamma (*(int*)(0x0204))
int main(void)
{
int t = gamma; // compiles to MOV.W &0x204, &t
return t;
}

produces exactly the same code.
--- In m..., Aaron Greer wrote:
>
> OCY what you fail to realize is that this is a specific tool chain
issue specific to C.
> Open up IAR V3.42 and give it a try, you'll see what I'm talking about.
>
> ----- Original Message -----
> From: "old_cow_yellow"
> To: m...
> Sent: Wednesday, June 11, 2008 3:15:07 PM (GMT-0700) America/Denver
> Subject: [msp430] Re: Accesing Data on Flash
>
> I do not understand c (nor use c). But I think the statement:
> "_root const int _gamma @ 0x0204 = 3;"
> does not do any good.
>
> I think it does not make "_gamma" nor "@ 0x0204" equal to 3.
>
> You code "works" the same way with or without that statement.
> That is, the variable t is initialize with the value of "@ 0x204"
> which is usually not 3.
>
> --- In m... , Aaron Greer wrote:
> >
> > I've been trying a few things with IAR, and I am also unable to make
> their examples work.
> >
> > Here is the error I get when declaring a global such as:
> > volatile const int gamma @ 0x0204 = 3;
> > Error[Be022]: location address not allowed for initialized variables
> (writable variables without the __no_init attribute)
> >
> > So, I came up with something that will probably work for you. It
> only requires two changes to the variable declarations and the
> addition of a macro (for each variable).
> >
> > Before:
> > const int gamma @ 0x0204 = 3;
> > int main(void){
> > int t = gamma; // compiles to MOV.W #0x3, &t
> > }
> >
> > After :
> > _root const int _gamma @ 0x0204 = 3;
> > #define gamma (*(int*)(0x0204))
> > int main(void){
> > int t = gamma; // compiles to MOV.W &0x204, &t
> > }
> >
> > I know it's not the cleanest workaround in the world, especially for
> a large number of variables, but it does work and doesn't require you
> to modify the code at all the access points.
> >
> > Aaron
> >
> > ----- Original Message -----
> > From: "gab0ar"
> > To: m...
> > Sent: Wednesday, June 11, 2008 1:03:09 PM (GMT-0700) America/Denver
> > Subject: [msp430] Re: Accesing Data on Flash
> >
> >
> >
> >
> >
> >
> >
> > Thanks for answering.
> >
> > Your guess is right, i need this variable in FLASH, in fact i need it
> > to be specifically on the location MY_VAR which is the start of a
> > FLASH page (which in time i will erase and write the new values).
> >
> > According to IAR documentation the @ operator used to locate
variables
> > at fixed addresses can only be use with "const" o "no init". As I
> > need this variables to have some initial values the "__no_init" is
> > discarded, so the "const" is a must.
> >
> > On the other hand, i need to tell the compiler that the value of that
> > variable may change between different access (when i change the flash
> > on execution time), so it needs to read the values instead of the
> > default data.
> > I quote this from the IAR documentation (page 35 MSP430 C/C++ IAR
> > Compiler: Reference Guide):
> >
> > "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 */"
> >
> > Since that seemed to be the exact solution to my problem, i used the
> > last example (volatile const) with no problems until the 3.42 crossed
> > my path.
> >
> > I tried your solution
> >
> > a = *(tMyVar*)(&myVar);
> >
> > and it really works! But as i mentioned before in reality i have a
> > large structure with a lot of variables. And around 45K of code which
> > i dont want to search looking for all the access to such
variables. Im
> > hoping there is another way (or trick) to tell the compiler to use
> > always the variable and not the value when optimizing.
> >
> > Thanks again for the help.
> >
> > --- In m... , Aaron Greer wrote:
> > >
> > > My guess is that you're using const because the value is located in
> > flash rather than RAM.
> > > It seems obvious that your problem is being caused by the
> > optimization engine.
> > > Here is what I'd suggest.
> > >
> > > instead of doing this:
> > > a = myVar;
> > >
> > > try doing this:
> > > a = *(tMyVar*)(&myVar);
> > >
> > > Technically, they should be equivalent, but it might force the
> > optimizer into doing what you want instead of removing the memory
> > reference and replacing it with the default value.
> > >
> > > Aaron
> > >
> > > ----- Original Message -----
> > > From: "gab0ar"
> > > To: m...
> > > Sent: Wednesday, June 11, 2008 9:57:18 AM (GMT-0700) America/Denver
> > > Subject: [msp430] Accesing Data on Flash
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > Hello, I had a problem when upgrading from IAR 3.20 to 3.42.
> > >
> > > Some time ago I needed to declare an initialized variable on a
fixed
> > > location on flash. This variable would change on execution time,
and
> > > the value would be reffered from other parts of the code. I
found the
> > > following to work:
> > >
> > > Declare on a .h
> > >
> > > #define DEFAULT_VALUE 8
> > > #define MY_LOCATION 0xF000
> > >
> > > extern volatile const tMyVar myVar @ MY_LOCATION = {
> > > DEFAULT_VALUE
> > > }
> > >
> > > And when referencing that variable from other places:
> > >
> > > a = myVar;
> > >
> > > Generated the following Assembly output:
> > >
> > > MOV.B &0xfa00, 0(R12)
> > >
> > >
> > > On version 3.42 the "volatile const" directive is not permitted
> > > anymore so I deleted the volatile:
> > >
> > > #define DEFAULT_VALUE 8
> > > #define MY_LOCATION 0xF000
> > >
> > > extern const tMyVar myVar @ MY_LOCATION = {
> > > DEFAULT_VALUE
> > > }
> > >
> > > But when I reference from other parts of the code I get the
following
> > >
> > > a = myVar;
> > >
> > > generates:
> > >
> > > MOV.B #0x8, R14
> > >
> > > This copies the Default value to "a" instead of the content of the
> > > direction.
> > >
> > > I would like to know how to make the code behave like it did on
3.2.
> > >
> > > Its important to point that this is only an example, in my project
> > > tMyVar is a large structure, and that I make multiple calls along
> > > different CPP files and this CPP are always Optimized for SIZE on
> HIGH
> > > (maximum optimization).
> > >
> > > I hope I made myself clear, thanks in advance for your help.
> > >
> > >
> > >
> > >
> > >
> >
> >
> >
> >
> >
>