Trying to read hardware memory from pointer?

B

Brad

Hi,

Am trying to read one byte at location 0xFFF0 000E in an embedded system.

I cast a pointer to int, then try to stuff the above address in, then
reference whats at the location? wont compile, tried many different
variations of this; any ideas appreciated.
 
I

Ian Collins

Brad said:
Hi,

Am trying to read one byte at location 0xFFF0 000E in an embedded system.

I cast a pointer to int, then try to stuff the above address in, then
reference whats at the location? wont compile, tried many different
variations of this; any ideas appreciated.
Show us what you have tried, what do you mean by "cast a pointer to int"?
 
J

John Devereux

Brad said:
Hi,

Am trying to read one byte at location 0xFFF0 000E in an embedded system.

I cast a pointer to int, then try to stuff the above address in, then
reference whats at the location? wont compile, tried many different
variations of this; any ideas appreciated.

unsigned char data = *((unsigned char*)0xFFF0000E);
 
S

suresh

John said:
unsigned char data = *((unsigned char*)0xFFF0000E);

I don't see any compilation error in this code. Is it in global scope
by any chance?
Post the complete (minimal compilable) code.

Consider adding volatile to the typecast. This may not solve your
current problem though.
 
V

Vladimir Oka

suresh opined:
I don't see any compilation error in this code. Is it in global scope
by any chance? Post the complete (minimal compilable) code.

You seem to have misinterpreted the attributions. The OP (Brad) did not
post any code. John then posted the line above (which looks OK to me,
too). We're still to hear from the OP whether it solves his problem.
Consider adding volatile to the typecast.

Another good idea for the OP.

--
Falling in love makes smoking pot all day look like the ultimate in
restraint.
-- Dave Sim, author of "Cerebus".

<http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>
 
S

suresh

suresh said:
I don't see any compilation error in this code. Is it in global scope
by any chance?
Post the complete (minimal compilable) code.

Consider adding volatile to the typecast. This may not solve your
current problem though.

Oops... sorry. Don't consider my last statement unless the content of
that memory is volatile.
 
R

Rod Pemberton

Brad said:
Hi,

Am trying to read one byte at location 0xFFF0 000E in an embedded system.

I cast a pointer to int, then try to stuff the above address in, then
reference whats at the location? wont compile, tried many different
variations of this; any ideas appreciated.

This is compiler and environment specific.
(All examples are untested...)

Example 1) OW 16-bit DOS

unsigned char far *address;
unsigned char byte;
address=MK_FP(0xFFF0,0x000E);
byte=*address;

Example 2) OW 32-bit DOS

unsigned char *address;
unsigned char byte;
address = (unsigned char *)(((unsigned long)0xFFF0)<<4)+((unsigned
long)0x000E);
byte=*address;

Example 3) DJGPP 32-bit DOS (segmented memory model)

unsigned char byte;
byte=_farpeekb(_dos_ds,(((unsigned long)0xFFF0)<<4)+((unsigned
long)0x000E));


HTH,

Rod Pemberton
 
B

Brad

Vladimir Oka said:
suresh opined:


You seem to have misinterpreted the attributions. The OP (Brad) did not
post any code. John then posted the line above (which looks OK to me,
too). We're still to hear from the OP whether it solves his problem.


Another good idea for the OP.

--
Falling in love makes smoking pot all day look like the ultimate in
restraint.
-- Dave Sim, author of "Cerebus".

<http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>

Wow, you guys are fast. I was trying code on a different computer, didnt
have examples here, but was trying to force the literal memory address into
the pointer, then reference it, here the example simply references the
address, this is so awesome! Since Ive spent time having to not consider
any access to physical memory, this stumped me. I will go try this code out
soon. It will be reading an area of flash. The code module itself
references everything from an offset, this would be simply offset 0xE but
its always put into flash.

Its odd doing it this way but will work out perfectly. will try and post
results. Thanks for everyones input!

Brad
 
W

Walter Roberson

unsigned char data = *((unsigned char*)0xFFF0000E);

I went looking at the ANSI C89 reference thinking that was wrong, but
I was mistaken, and learned somethings along the way. It was not, though,
about the obvious question of whether a number can be converted to a pointer.

What I was looking at was whether the 0xFFF0000E constant had the
right type: I was thinking "Ah, but if int is only 16 bits, won't
that constant get truncated, seeing as it does not have a suffix?".
The C89 standard indicates, though, that an integer constant has
the smallest type out of a given list that will fit the numeric value.

And what I also found in the C89 standard was that the type list considered
is different for decimal constants than for octal or hex constants.
I had thought that all forms of constants were equivilent, but they
aren't.

On 16 bit int 2's complement systems, the decimal constant 65535
would be represented as type long int, but the hex constant 0xFFFF
would be represented as type unsigned int. That would imply that,
for example, on such a system, sizeof(65535) > sizeof(0xFFFF).

There's gotta be a good Obfuscated C trick in there somewhere ;-)
 
B

Brad

Walter Roberson said:
I went looking at the ANSI C89 reference thinking that was wrong, but
I was mistaken, and learned somethings along the way. It was not, though,
about the obvious question of whether a number can be converted to a
pointer.

What I was looking at was whether the 0xFFF0000E constant had the
right type: I was thinking "Ah, but if int is only 16 bits, won't
that constant get truncated, seeing as it does not have a suffix?".
The C89 standard indicates, though, that an integer constant has
the smallest type out of a given list that will fit the numeric value.

And what I also found in the C89 standard was that the type list
considered
is different for decimal constants than for octal or hex constants.
I had thought that all forms of constants were equivilent, but they
aren't.

On 16 bit int 2's complement systems, the decimal constant 65535
would be represented as type long int, but the hex constant 0xFFFF
would be represented as type unsigned int. That would imply that,
for example, on such a system, sizeof(65535) > sizeof(0xFFFF).

There's gotta be a good Obfuscated C trick in there somewhere ;-)

Hey Thanks for that Walter, this is so interesting, and while trying the
solution, the compiler croaks for NO apparent reason at least to me,


1 unsigned char valIsaDot = 0;
2 unsigned char valBootVer = 0;
3
4 unsigned char *pBootVer = (unsigned char *)0xFFF0000E;
5 valBootVer = *pBootVer;
6
7
8 unsigned char *pBootDot = (unsigned char *)0xFFF0000F;
9 valIsaDot = *pBootDot;



The compiler says error at line 8 near 'unsigned' If line 8 and 9 are
removed, it compiles fine. There is nothing wrong with the spelling, it
simply wont allow this. On line 7 I add some extra task like int foo =0;
doesnt matter. If I take out the '=' on line 8 and have only the
definition? same error, line 8 near unsigned.




1// unsigned char valIsaDot = 0;
2// unsigned char valBootVer = 0;
3
4 unsigned char *pBootVer = (unsigned char *)0xFFF0000E;
5 unsigned char valBootVer = *pBootVer;
6
7
8 unsigned char *pBootDot = (unsigned char *)0xFFF0000F;
9 unsigned char valIsaDot = *pBootDot;

Do this? it compiles fine and works exactly right. (thanks again btw)


If there are no syntax errors, why does it refuse to accept the line 8
command before?
 
W

Walter Roberson

the compiler croaks for NO apparent reason at least to me,
1 unsigned char valIsaDot = 0;
2 unsigned char valBootVer = 0;
3
4 unsigned char *pBootVer = (unsigned char *)0xFFF0000E;
5 valBootVer = *pBootVer;
6
7
8 unsigned char *pBootDot = (unsigned char *)0xFFF0000F;
9 valIsaDot = *pBootDot;
The compiler says error at line 8 near 'unsigned' If line 8 and 9 are
removed, it compiles fine.

Are you using C89 or C99? Your line 5 is an assignment statement (executable)
and your line 8 is a declaration (an initialization rather than an assignment
statement). C89 does not allow declarations after the first executable statement
in any given block. C99 DOES allow declarations to be mixed into code.

Try moving line 8 to between line 4 and 5 and see if that makes a difference.
 
K

Keith Thompson

Brad said:
Hey Thanks for that Walter, this is so interesting, and while trying the
solution, the compiler croaks for NO apparent reason at least to me,


1 unsigned char valIsaDot = 0;
2 unsigned char valBootVer = 0;
3
4 unsigned char *pBootVer = (unsigned char *)0xFFF0000E;
5 valBootVer = *pBootVer;
6
7
8 unsigned char *pBootDot = (unsigned char *)0xFFF0000F;
9 valIsaDot = *pBootDot;



The compiler says error at line 8 near 'unsigned' If line 8 and 9 are
removed, it compiles fine. There is nothing wrong with the spelling, it
simply wont allow this. On line 7 I add some extra task like int foo =0;
doesnt matter. If I take out the '=' on line 8 and have only the
definition? same error, line 8 near unsigned.

Does your compiler really say "error at line 8", or does it tell you
*what* the error is?

Or maybe it doesn't like the line numbers.

If I wrap the lines in a function definition and compile with gcc, it
compiles without error. If I use "-ansi -pedantic", I get:

tmp.c: In function `foo':
tmp.c:10: warning: ISO C90 forbids mixed declarations and code

I suspect that's the cause of your problem. If you had posted actual
code (adding line numbers doesn't help) *and* shown us the exact error
message, I probably wouldn't have to guess.
 
B

Brad

Keith Thompson said:
Does your compiler really say "error at line 8", or does it tell you
*what* the error is?

Or maybe it doesn't like the line numbers.

If I wrap the lines in a function definition and compile with gcc, it
compiles without error. If I use "-ansi -pedantic", I get:

tmp.c: In function `foo':
tmp.c:10: warning: ISO C90 forbids mixed declarations and code

I suspect that's the cause of your problem. If you had posted actual
code (adding line numbers doesn't help) *and* shown us the exact error
message, I probably wouldn't have to guess.

Well thanks for that info, it was actual code from the part that failed.
Compiler is command line running on an old WinNT machine, Microsoft C from
the 90's, and its calling a compiler and asm from a company called Diab
Systems.

The error is how I saw it:

error at line (actual line) near 'unsigned'.

Thats all it gives for an excuse. Wish it would at least guess at something.
I added line numbers thought it would show it easier.
It seemed odd that it would take the first statement formatted that way,
then a second one is not allowed?


Brad
 
B

Brad

Walter Roberson said:
Are you using C89 or C99? Your line 5 is an assignment statement
(executable)
and your line 8 is a declaration (an initialization rather than an
assignment
statement). C89 does not allow declarations after the first executable
statement
in any given block. C99 DOES allow declarations to be mixed into code.

Try moving line 8 to between line 4 and 5 and see if that makes a
difference.

Oh I see! The light might have come on. So in the block area, line 8 is
rejected because it is or has a declaration?

So line 8 is put back to line 4/5 and its happy. Im not realizing all of
it, what is the "NEXT" thing that signals the end of the block? IOW, where
is the next place below where line 8 could have gone?

Brad
 
I

Ian Collins

Brad said:
Well thanks for that info, it was actual code from the part that failed.
Compiler is command line running on an old WinNT machine, Microsoft C from
the 90's, and its calling a compiler and asm from a company called Diab
Systems.

The error is how I saw it:

error at line (actual line) near 'unsigned'.

Thats all it gives for an excuse. Wish it would at least guess at something.
I added line numbers thought it would show it easier.
It seemed odd that it would take the first statement formatted that way,
then a second one is not allowed?

Unless you have a C99 compiler, line 8 is an error because it follows
line 5 which is 'code' and you can't mix declarations and code.

Swap lines 5 and 8 and all will be well.
 
W

Walter Roberson

[on mixing code and declarations]
Im not realizing all of
it, what is the "NEXT" thing that signals the end of the block? IOW, where
is the next place below where line 8 could have gone?

A statement that begins with a type indicator is a declaration.
Any other kind of statement is executable.

Traditional C and C89 do not permit mixing declarations with executable
code -- though you might find pre- C99 compilers that permit such a thing
as an extension.

(Comments and preprocessor lines are not statements at all, so
neither marks the end of declarations.)
 
K

Keith Thompson

Brad said:
Keith Thompson said:
Brad said:
Hey Thanks for that Walter, this is so interesting, and while trying the
solution, the compiler croaks for NO apparent reason at least to me,


1 unsigned char valIsaDot = 0;
2 unsigned char valBootVer = 0;
3
4 unsigned char *pBootVer = (unsigned char *)0xFFF0000E;
5 valBootVer = *pBootVer;
6
7
8 unsigned char *pBootDot = (unsigned char *)0xFFF0000F;
9 valIsaDot = *pBootDot;
[...]
If I wrap the lines in a function definition and compile with gcc, it
compiles without error. If I use "-ansi -pedantic", I get:

tmp.c: In function `foo':
tmp.c:10: warning: ISO C90 forbids mixed declarations and code

I suspect that's the cause of your problem. If you had posted actual
code (adding line numbers doesn't help) *and* shown us the exact error
message, I probably wouldn't have to guess.

Well thanks for that info, it was actual code from the part that failed.
Compiler is command line running on an old WinNT machine, Microsoft C from
the 90's, and its calling a compiler and asm from a company called Diab
Systems.

The error is how I saw it:

error at line (actual line) near 'unsigned'.

Thats all it gives for an excuse. Wish it would at least guess at something.

That's really the *whole* error message? It just said "error", not
"syntax error"?

If that's really all it said, it's a lousy error message. If it
actually said "syntax error", this is a good illustration of why you
need to copy-and-paste the entire message.

gcc, for example, can handle mixed declarations and statements.
They're allowed in C99, but not in C90 -- but gcc also supports them
in its C90-plus-extensions mode. That's why it's able to give such a
clear error message in this case; it already handles them internally,
and just needs to complain if it's in strict C90 mode. The compiler
you're using probably doesn't support mixed declarations and
statements in any mode. Once it sees the first statement in a block,
it stops looking for declarations; rather than interpreting "unsigned
char *pBootDot" as a misplaaced declaration, it just doesn't
understand it.
 
I

Ian Collins

Keith said:
That's really the *whole* error message? It just said "error", not
"syntax error"?

If that's really all it said, it's a lousy error message. If it
actually said "syntax error", this is a good illustration of why you
need to copy-and-paste the entire message.
I wouldn't be surprised, my memories of the Diab compiler aren't very
pleasant.
 
O

Old Wolf

Rod said:
address = (unsigned char *)(((unsigned long)0xFFF0)<<4)+((unsigned
long)0x000E);

Are you trying to enter the IOCCC ?

This is the same as writing:

address = (unsigned char *)0xFFF0000EUL;

and as noted by Walter Roberson, the UL suffix is unnecessary
as the compiler selects the right type (uint or ulong) automatically.
 
R

Rod Pemberton

Old Wolf said:
Are you trying to enter the IOCCC ?

No. It was written as if 0xFFF0 and 0x000E were contained in variables.
This is frequently the case for Intel segments and offsets.
This is the same as writing:

address = (unsigned char *)0xFFF0000EUL;

That's incorrect a 32-bit compiler which that example was for. It _may_ be
correct for some 16-bit compilers (i.e., I think the OW 16-bit MK_FP does
this...). You've placed the segment in the upper word and the offset in the
lower word. For a 32-bit compiler, that produces an address near 4Gb. The
correct address is below 1Mb (no more than 20-bits). It is the same as
this:

address = (unsigned char *)0x000FFF0EUL;


0xFFF0 << 4 = 0xFFF00
0xFFF00 + 0x000E = 0xFFF0E
and as noted by Walter Roberson, the UL suffix is unnecessary
as the compiler selects the right type (uint or ulong) automatically.


HTH,

Rod Pemberton
 

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
474,183
Messages
2,570,965
Members
47,511
Latest member
svareza

Latest Threads

Top