Pointers to specific memory addresses

M

moschops

In coding some embedded software, I frequently find that I need to read
from a specific memory location; it's a hard-wired location that always
contains the same information. A register, for example.

To do so, I tend to define a pointer along the lines of

int* pChipVersionNumber = 0x1000001

for example, where 0x10000001 is the permanent location of the data I'm
interested in.

The compiler I compile embedded code with (in the VDSP environment)
spits out a warning that I've created a pointer in this way, but
generates working code anyway.

Why would the compiler be warning me about this? Are there compilers
that would produce errors, rather than warnings? Is there some other way
I should be explicitly defining a location in memory to read?

To reiterate, these memory locations are not system variables with
nicely defined labels that I can fetch; they're raw locations.

It's common to use predefined values supplied with the chip support
software instead of stating the memory location myself, but in rooting
through the support code I find it usually ends up doing much the same
thing anyway.

'Chops
 
P

Pete Becker

int* pChipVersionNumber = 0x1000001

for example, where 0x10000001 is the permanent location of the data I'm
interested in.

The compiler I compile embedded code with (in the VDSP environment)
spits out a warning that I've created a pointer in this way, but
generates working code anyway.

Why would the compiler be warning me about this? Are there compilers
that would produce errors, rather than warnings? Is there some other
way I should be explicitly defining a location in memory to read?

Standard C++ does not support hard-coded addresses. Compilers for
embedded systems usually have a facility for this sort of thing.
Alternatively, you can usually just add a cast:

int *p = (int*)0x1000001;
 
R

red floyd

Pete said:
-
Standard C++ does not support hard-coded addresses. Compilers for
embedded systems usually have a facility for this sort of thing.
Alternatively, you can usually just add a cast:

int *p = (int*)0x1000001;

Better is to make it a const pointer to a volatile object,
so the compiler won't optimize it (got burned by this with
a TI 34020 compiler).

int volatile *const pSOME_REG =
reinterpret_cast<int volatile *>(0x10000001);

And, if it's a read only register :

volatile int *const pSOME_RO_REG =
reinterpret_cast<int volatile const int*>(0x10000001);



volatile const int* const
 
P

Pete Becker

Better is to make it a const pointer to a volatile object,
so the compiler won't optimize it (got burned by this with
a TI 34020 compiler).

int volatile *const pSOME_REG =
reinterpret_cast<int volatile *>(0x10000001);

And, if it's a read only register :

volatile int *const pSOME_RO_REG =
reinterpret_cast<int volatile const int*>(0x10000001);



volatile const int* const

Maybe, maybe not. But it's a separate question from what was asked.
 
M

moschops

red said:
Better is to make it a const pointer to a volatile object,
so the compiler won't optimize it (got burned by this with
a TI 34020 compiler).

Good thinking, many thanks. I'll probably go easy on the C++ style
reinterpret casting (mainly because the other guy working on this
doesn't speak C++), but it's a good idea.

'Chops
 
T

Tomás Ó hÉilidhe

moschops:
In coding some embedded software, I frequently find that I need to read
from a specific memory location; it's a hard-wired location that always
contains the same information. A register, for example.


You're using C++ for embedded? Really? Out of curiosity, what
microcontroller are you using that you can get a C++ compiler for? Is
are either of the microcontroller or the compiler expensive?


To do so, I tend to define a pointer along the lines of

int* pChipVersionNumber = 0x1000001

for example, where 0x10000001 is the permanent location of the data I'm
interested in.

The compiler I compile embedded code with (in the VDSP environment)
spits out a warning that I've created a pointer in this way, but
generates working code anyway.



I don't like when compilers are too liberal. This should be an error.


Why would the compiler be warning me about this?



Be glad that you don't know! If you were to use this compiler for quite
a while, you might some day write code that erroneously uses an integer
for an address (e.g. you write int *p = 9 instead of int *p = 0).

Are there compilers
that would produce errors, rather than warnings?


Yes, all the good ones will give errors for type mismatches.

Is there some other way
I should be explicitly defining a location in memory to read?


As people have said, use a cast:

int *p = (int*)0x6872;
 
M

moschops

Tomás Ó hÉilidhe said:
You're using C++ for embedded? Really? Out of curiosity, what
microcontroller are you using that you can get a C++ compiler for? Is
are either of the microcontroller or the compiler expensive?

I'm using this -

http://www.analog.com/processors/visualDSP/testDrive.html

to write code for one of these -

http://www.vmetro.com/category3954.html

I don't like when compilers are too liberal. This should be an error.

Most of the time, I'm in favour of errors over warnings as well. In this
case, though, I'm torn. I create a pointer. The pointer has a value
which is the numerical address of a given unit of the memory. That
numerical address is conceptually an unsigned integer. When I look at
the memory, a pointer holding the address 0x10000001 is identical to an
unsigned integer of the value 0x10000001. The compiler sees a
difference, but the hardware doesn't. I can appreciate that the compiler
should to an extent hold my hand, but on the other hand in embedded work
I need to be close to the hardware.
Be glad that you don't know! If you were to use this compiler for quite
a while, you might some day write code that erroneously uses an integer
for an address (e.g. you write int *p = 9 instead of int *p = 0).

Surely I just _have_ quite deliberately written int* p = 9? Or, in this
case, int* p = 0x10000001 ?

'Chops
 
T

Tim H

The pointer has a value
which is the numerical address of a given unit of the memory.

YOU know that, but the compiler doesn't. On some platforms, not all
valid integers are valid pointers. The compiler is enforcing the
standard, which does not make guarantees about hardware.
That
numerical address is conceptually an unsigned integer. When I look at
the memory, a pointer holding the address 0x10000001 is identical to an
unsigned integer of the value 0x10000001.

It might be on YOUR hardware, but it's not on all hardware. The
contents of that memory are a set of bits. The standard can't know
what the implementation does with them.

Imagine for a moment a segmented platform, where pointers are a
segment:eek:ffset pair. That 0x10000001 initializer might mean segment
0x1000, offset 0x0001. Or it might mean linear address 0x10000001.
All the compiler is doing is forcing you to declare "I know what I am
doing, and I know this is not portable" by casting.

Imagine a platform that sets the high bit of pointers to indicate that
they are valid.
The compiler sees a
difference, but the hardware doesn't.

What about platforms where unaligned accesses are not allowed?
I can appreciate that the compiler
should to an extent hold my hand, but on the other hand in embedded work
I need to be close to the hardware.

So turn off those warnings or cast them away?
 
M

moschops

Tim H wrote:


It might be on YOUR hardware, but it's not on all hardware. The
contents of that memory are a set of bits. The standard can't know
what the implementation does with them.

Imagine for a moment a segmented platform, where pointers are a
segment:eek:ffset pair. That 0x10000001 initializer might mean segment
0x1000, offset 0x0001. Or it might mean linear address 0x10000001.

As an aside, even though I agree with what you say, it still grates with
me. I think I've probably become too close to this hardware (I've
spent almost a year with this one damn piece of kit) and I've stopped
thinking of the language and the hardware as separate entities; when I
can watch the memory change as I code, the two become inseparable. For
the most part it helps me write some neat code, but it's going to create
quite a shock when I move on to the next piece of hardware.
 
D

Default User

Tomás Ó hÉilidhe wrote:

You're using C++ for embedded? Really? Out of curiosity, what
microcontroller are you using that you can get a C++ compiler for? Is
are either of the microcontroller or the compiler expensive?

Many times a cross-compiler is used. For instance Green Hills for
compiling C++ to run under the VxWorks RTOS. Any number of boards
support that.




Brian
 
R

Rahul

In coding some embedded software, I frequently find that I need to read
from a specific memory location; it's a hard-wired location that always
contains the same information. A register, for example.

To do so, I tend to define a pointer along the lines of

int* pChipVersionNumber = 0x1000001

for example, where 0x10000001 is the permanent location of the data I'm
interested in.

The compiler I compile embedded code with (in the VDSP environment)
spits out a warning that I've created a pointer in this way, but
generates working code anyway.

Why would the compiler be warning me about this? Are there compilers
that would produce errors, rather than warnings? Is there some other way
I should be explicitly defining a location in memory to read?

To reiterate, these memory locations are not system variables with
nicely defined labels that I can fetch; they're raw locations.

It's common to use predefined values supplied with the chip support
software instead of stating the memory location myself, but in rooting
through the support code I find it usually ends up doing much the same
thing anyway.

'Chops

which cross-compiler are you using?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top