How to read/write an 'address' from a memory location......

I am trying to read an address from a memory location and then write into that memory location. i.e.

unsigned long * mem_pointer = 0x93700020; //Valid memory location on my hardware unsigned long mem_value = *mem_pointer; //Retrieve the value (another memory location) from //the pointer

The question is - How do i use the value at mem_value as an address? Basically, I want to do something like.

*(unsigned char *)mem_value = 10.

Thanks and warm regards, Rintu

Reply to
aeroboro221
Loading thread data ...

Your question / posting is unclear.

Karthik Balaguru

Reply to
karthikbalaguru

Please keep your source lines under 72 chars (67 is better) to avoid those silly line wraps. Also avoid the // comment style, which doesn't survive line wraps, and is even illegal in C90 withut extensions.

You have:

unsigned long *mem_pointer =

where is a suitable description of an address in your machine. To access the data at that address just use a *, i.e.:

*mem_pointer = 10; or if (10 == *mem_pointer) /* do something */; or something_else = *mem_pointer.

Note that a cast is not a legal lvalue. I.e:

(unsigned char *) = anything;

The type pointed to is built into the value of mem_pointer (unless that type is 'void').

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

Please don't wrap code examples when you post them.

unsigned long **p1, *p2, v;

p1 = (unsigned long **)0x93700020; p2 = *p1; v = *p2;

or if you prefer a one-liner:

v = **((unsigned long **)0x93700020);

--
Grant Edwards                   grante             Yow! Hello, GORRY-O!!
                                  at               I'm a GENIUS from HARVARD!!
                               visi.com
Reply to
Grant Edwards

[....]

That should work, assuming that "unsigned long" is the same size as a pointer on your system. But as Grant Edwards points out, it's easier to use the compiler's type system directly, and just cast the address to be a pointer to a pointer, rather than a pointer to an unsigned long (which is another pointer in disguise):

unsigned char **mem_pointer = 0x93700020; foo = **mem_pointer;

or, if you prefer: unsigned char **mem_pointer = 0x93700020; unsigned char *mem_value = *mem_pointer; foo = *mem_value;

--
   Wim Lewis , Seattle, WA, USA. PGP keyID 27F772C1
Reply to
Wim Lewis

[...]

Using physical addresses in C code is dirty hack. You should not do that. Also you should never use the nonsense like "unsigned long".

  1. In the linker file, define a section "foobar" at the required location.
  2. Place a variable there: #pragma section "foobar" u32 * mem_pointer;
  3. Use this pointer as any other variable.

Vladimir Vassilevsky DSP and Mixed Signal Consultant

formatting link

Reply to
Vladimir Vassilevsky

Really? I've never heard of anyone doing that. It seems cumbersome; you could end up with hundreds of sections in the object file. And you each definition appears twice.

gcc lets you define variables in the linker script

PROVIDE( PORT0 = 0xE0020000);

Then you can reference it with

extern volatile unsigned long PORT0;

I don't quite see the advantage over the usual

#define PORT0 (*(volatile unsigned long *)(0xE0020000))

Except.... aha! It should appear nicely in the debugger! Must try this now! :)

--

John Devereux
Reply to
John Devereux

That's even less portable than the OPs "hack".

--
Grant Edwards                   grante             Yow! I'm dressing up in
                                  at               an ill-fitting IVY-LEAGUE
                               visi.com            SUIT!!  Too late...
Reply to
Grant Edwards

I agree. Allocating a separate section for each location you want to "hard-wire" is overly complex and fragile.

In my experience, the former method using PROT0 = 0xE0020000 will be visible to the debugger, the latter might or might not.

--
Grant Edwards                   grante             Yow! Now I am depressed ...
                                  at               
                               visi.com
Reply to
Grant Edwards

Which "that" --- the one you read the address from, or the one the address specifies?

An address kept in a variable is called a pointer, in C programs. So mem_value should be of a pointer type, rather than an integer. Consequentially, mem_pointer should be a pointer-to-pointer-to-something type, e.g.

some_type **mem_pointer = ...; some_type *mem_value = *mem_pointer; some_type the_actual_thing = *mem_value;

And what's keeping you from doing exactly that?

But this all hides a probably more important question: why do you think you should be doing this?

Reply to
Hans-Bernhard Bröker

My problem is: I have two processors exchanging data over a shared section of memory. Now before processor 1 can write the data for processor 2 (in the shared memory), processor 1 needs to tell processor 2 where exactly it will be writing. Thats where i was coming from - processor 1 basically needs to write an "address" into a predefined location for processor 2 and that "address" will hold the actual data for processor 2.

Thanks a lot for all your clarifications. I should try some of them now!

Warm regards, Rintu

Reply to
aeroboro221

... snip ...

That is outside the abilities of the C language, which has no intrinsic knowledge of multiple processes and managing them. However, if your description is adequate, the following might work:

Global (common memory): int running = 1; Type *ptr = NULL;

Sender code fragment: do { /* prepare data */ while (ptr && running) continue; if (running) { ptr = malloc(sizeof *ptr); *ptr = data; } } while (running)'

Receiver code fragment: do { while (!ptr && running) continue; if (running) { rcvdata = *ptr; free(*ptr); ptr = NULL; /* process rcvdata */ } } while (running);

Note that either process can shut down the interaction by setting running to zero. Sender has a local variable named data, and receiver has one named rcvdata. The processes are in strict sync, i.e. one item of data causes one item to be transmitted, and nothing more is done until that item is received. Similarly the receiver can do nothing while waiting for new data to be prepared.

Note that malloc failing in sender is a fatal error. The initialization values ensure that the sender runs first. The definition of 'Type' controls the amount of data transferred. The 'continue' statements can be changed into function calls to do other things.

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

. . .

Ah, the pleasures of using dual-port RAM. You need to have a good handle on the use of semaphores so that the data is not overwritten before the second processor has read it.

--
John B
Reply to
John B

No. It only needs to do that as it *finishes* writing there. Allowing the reader to find out you've started writing, before you're finished doing it, will cause nasty race conditions.

No. You rather probably shouldn't be using addresses for that part of the communication --- not even in "quotes". Use indices into a shared array of bytes instead. The difference being that the two processors don't have to agree on where in their respective address space that shared memory actually is. Pointers are pretty much *always* the wrong thing to export from any program to the outside world (or another program, for that matter).

Reply to
Hans-Bernhard Bröker

The algorithm of exchanging data once the addresses are known to both processors is pretty much done. The way to communicate the address is where I was kind of stuck. I just tested one of the ways described here and it seems to work!

Thanks again!

Regards, Rintu

Reply to
aeroboro221

By the way, there is no concept of semaphores between two processors right? What I can think of is a flag shared between the two processors by means of shared RAM or a messaging unit.

Reply to
aeroboro221

So now you have a program that *seems to work.

--
	mac the naïf
Reply to
Alex Colvin

Sure there is.

A flag + a couple atomic operations == semaphore.

--
Grant Edwards                   grante             Yow! People humiliating
                                  at               a salami!
                               visi.com
Reply to
Grant Edwards

I have no idea what this refers to - you have omitted the quotation portion. However, if you are referring to my earlier answer, the state of 'ptr' functions as a data_ready flag. It is not a good process for simultaneous action.

--
 Chuck F (cbfalconer at maineline dot net)
   Available for consulting/temporary embedded and systems.
Reply to
CBFalconer

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.