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.
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.
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):
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! :)
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.
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!
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.
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.
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).
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!
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.
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.
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.