Can you help me to understand this define?

S

silusilusilu

I don't understand this define
#define timer (*(volatile unsigned long *) (0x100))
this shoud be able to put timer value in 0x100 memory location, so if
i put timer=50:
(*(volatile unsigned long *) (0x100))=50, right?
what it means?
Thanks
 
I

Ian Collins

I don't understand this define
#define timer (*(volatile unsigned long *) (0x100))
this shoud be able to put timer value in 0x100 memory location, so if
i put timer=50:
(*(volatile unsigned long *) (0x100))=50, right?
what it means?

What don't you understand? You appear to have deciphered the code
correctly.
 
J

Jens Thoms Toerring

I don't understand this define
#define timer (*(volatile unsigned long *) (0x100))
this shoud be able to put timer value in 0x100 memory location, so if
i put timer=50:
(*(volatile unsigned long *) (0x100))=50, right?
what it means?

Let's start somewhat simpler

( unsigned long * ) 0x100

tells the compiler that the address 0x100 is supposed to be
the address of an unsigned long variable, i.e. when it
writes a value to it it converts the value to an unsigned
long and writes as many bytes, starting at address 0x100,
to the memory as an unsigned long has (i.e. if an unsigned
long has 4 bytes on your machine it will write to the memory
cells at address 0x100, 0x101, 0x102 and 0x103).

The next thing is the 'volatile':

( volatile unsigned long * ) 0x100

It instructs the compiler that when you tell it to write to
or read from an address it should do that even it may look to
the compiler as if it's redundant. Optimizing compilers try
to figure out what are redundant operations and simply throw
those away - that's fine most of the time but when you're
dealing with e.g. hardware registers where reading from or
writing to has side effects that can be not what you want.

Now you have

* ( volatile unsigned long * ) 0x100 = 50;

It tells the compiler to unconditionally create machine
instructions that write an unsigned integer with value 50 to
the memory locations starting at addess 0x100.

Regards, Jens
 
S

silusilusilu

Thanks to this beautiful answer....
Let's start somewhat simpler

( unsigned long * ) 0x100

tells the compiler that the address 0x100 is supposed to be
the address of an unsigned long variable, i.e. when it
writes a value to it it converts the value to an unsigned
long and writes as many bytes, starting at address 0x100,
to the memory as an unsigned long has (i.e. if an unsigned
long has 4 bytes on your machine it will write to the memory
cells at address 0x100, 0x101, 0x102 and 0x103).

It makes 0x100 the address of a pointer?it's a cast operation?
The next thing is the 'volatile':

( volatile unsigned long * ) 0x100

It instructs the compiler that when you tell it to write to
or read from an address it should do that even it may look to
the compiler as if it's redundant. Optimizing compilers try
to figure out what are redundant operations and simply throw
those away - that's fine most of the time but when you're
dealing with e.g. hardware registers where reading from or
writing to has side effects that can be not what you want.
ok

Now you have

* ( volatile unsigned long * ) 0x100 = 50;

It tells the compiler to unconditionally create machine
instructions that write an unsigned integer with value 50 to
the memory locations starting at addess 0x100.

i don't understand first *.... if i write ( volatile unsigned long * )
0x100 = 50, what i obtain? If i think it linke a pointer, shouldn't be
*address=50?
thanks
 
I

Ian Collins

(e-mail address removed) wrote:

[Please don't snip attributions]
> Jens Thoms Toerring wrote:

i don't understand first *.... if i write ( volatile unsigned long * )
0x100 = 50, what i obtain? If i think it linke a pointer, shouldn't be
*address=50?

You almost there, (volatile unsigned long*) casts 0x100 to a pointer to
volatile unsigned long. In two steps:

volatile unsigned long* address = volatile unsigned long*)0x100;

*address = 50;
 
J

Jens Thoms Toerring

It makes 0x100 the address of a pointer?it's a cast operation?

Yes. '0x100' alone is just an integer value. Putting the cast
'(unsigned long *)' in front of it tells the compiler that
while it looks like a number it's actually to be treated as
a pointer.
i don't understand first *.... if i write ( volatile unsigned long * )
0x100 = 50, what i obtain? If i think it linke a pointer, shouldn't be
*address=50?

I guess Ian already has made the point clear - the '*' in front of
a pointer tells that you want to change what the pointer is poin-
ting to (and not the pointers value itself, which you couldn't
do here anyway since the pointer value is the fixed value 0x100),
so it's, as you already suspect, just like

* address = 50;

Adding another set of (redundant) parentheses may make it clearer:

* ( ( volatile unsigned long * ) 0x100 ) = 50;

The '( ( volatile unsigned long * ) 0x100 )' bit is exactly the
same type 'address' has in the line above (if 'address' is a
pointer to volatile unsigned long).

Just a final bit of pedantry: what you do here invokes undefined
behaviour. The memory at 0x100 is not memory you obtained by e.g.
calling malloc() etc. or is the address of one of your variables.
So in "normal situations" you wouldn't be allowed to write to it
or read from it. But here it looks as if your system documentation
is giving you a special permission by defining what's going to
happen when you write to that address (e.g. setting up some system
timer). So, while it's undefined behaviour from a C point of view
(since the C language can't define what happens on all systems
when you write to address 0x100), your system documentation defines
it and you thus may do so. Of course, as a result your program will
rather likely not work on any other system - on some it could crash
and on others writing to 0x100 might format your hard disk or start
the self-destruction sequence;-)

Regards, Jens
 

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

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top