On Fri, 5 Nov 2010, yavin229 wrote:
> Hi Jim, I think my misunderstanding on how the variable types change my
> offset's is likely the source of all my problems. I would really like to
> understand the math behind the problem you see. So in the snip you took:
> #define MEMLOC 0x80840000
>
> volatile unsigned long int *memloc;
>
> memloc = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd,
> MEMLOC);
> assert(memloc != MAP_FAILED);
> So my 'getconf PAGE_SIZE' returns 4096(bytes?) so I should be able to
> configure offsets to anywhere in this range from this one mapping, is
> that correct?
Correct.
> You mentioned that adding 4 to my 'memloc' INT pointer would actually
> give me a 'memloc + 16 in bytes'. I guess I don't understand the
> translation. A 'char' and a (short) 'int' are both 8 bits long I thought?
A char is one byte (8 bits). An unsigned long int is 4 bytes (32bits).
So far I've not seen any code using short int's. I think a short int would
be 16bits.
> My thinking was i was adding 4 blocks of 8bits or 32 bits which traslates
> to 4 bytes or 0x80840000(byte address) + 4bytes = 0x80840004.
No. you declared memloc as unsigned long int * , so by default the compiler
will assume that offsets from memloc are in unsigned long int's (i.e.
4bytes at a time). So to the compiler memloc+1 the next unsigned long int ,
which is at 0x80840000 + 4 to get past the first unsigned long int at
0x80840000, etc
> One last question I had was if someone could help me understand the PEEK
> fuction:
I've never used the peek function. If you have a volative ... * pointer,
then just dereference it. i.e.
v=*memloc
will read (in this case) an unsigned long int from the memory address.
volatile char *memloc
...
c=*memloc
inputs the char/byte at the address
> int fd,diobits,diobits_post_change, dio_direction_bits,
> dio_direction_bits_post_change;
> diobits = PEEK8( (unsigned long)(memloc + 0x04));
>
> Lets say for this case I changed memloc to be a char:
>
> volatile unsigned char *memloc;
>
> Forgive my ignorance here but I am not sure what the 'unsigned long'
> after PEEK is doing here. Is it passing the result of my char+4 into the
> function as a unsigned long then spiting out a 'int' to my variable?
Neither do I really - I'd expect it to be (unsigned long *). It's a cast,
an instruction to the compiler to use the result of the following
expression as another type of object.
If you are wanting to read bytes from IO space use unsigned char *
Then memloc+4 will be what you think it is.
If you are reading 4 byte ints (as you may need to do when access system
config registers - the ep93xx manual will tell you!) then
use unsigned long int * and divide any offsets by 4, before using the
numbers in code.
or
use unsigned char * and use offsets as is, but cast the point to
unsigned long int when using, i.e.
unsigned int val;
volatile unsigned char *memloc;
memloc = (unsigned char *)mmap(0, getpagesize(), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, MEMLOC);
val=(unsinged int *)(memloc+4);
this reads a 4 byte int from the address 4 bytes on from memloc.
I generally try and reduce casts to a minimum, so type my variables
properly for their use, and adjust any offset constants to account for
variable size.
HTH
Jim
If you don't really beleive it, try this small program...
#include <stdio.h>
main() {
volatile unsigned char *byteadd, *byteadd2;
volatile unsigned int *intadd,*intadd2;
byteadd=(unsigned char *)0x808a0000;
byteadd2=byteadd+4;
intadd=(unsigned int *)0x808a0000;
intadd2=intadd+4;
printf("byte %0x %0x\nint %0x %0x\n",byteadd,byteadd2,intadd,intadd2);
}
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|