#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2011
    Posts
    21
    Rep Power
    0

    Expression Clarification


    Hi Guys,
    still having a few issues with pointers...
    I came across this expression that obviously works and I can even see what it is doing, but I can not get my head around it.

    for the ARM uC I am using they have this definition:

    #define PB8 (*((volatile unsigned long *) 0x422181A0))

    and then the usage is so:

    PB8 = 1;

    can some one explain/breakdown the #define expression and what it means when you use it.

    this is sort of my interpretation of it:
    - (volatile unsigned long *) creates the pointer (without a name?)
    - (volatile unsigned long *) 0x422181A0) assigns the address being pointed at.
    - (*((volatile unsigned long *) 0x422181A0)) is actually the value stored at address.

    I probably got it completely wrong...

    any info relating to this usage would be appreciated.

    Thanks
    Luis
  2. #2
  3. I'm Baaaaaaack!
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Jul 2003
    Location
    Maryland
    Posts
    5,538
    Rep Power
    244
    There are more hardware oriented guys here who will probably correct me, but I believe this is creating an alias for a hardware address on the board somewhere. The stars and parentheses are to protect the expression from the compiler (#defines are plain textual substitutions) so that the compiler is happy. As a by the by, this sort of stuff will probably break when ARM64 is available.

    My blog, The Fount of Useless Information http://sol-biotech.com/wordpress/
    Free code: http://sol-biotech.com/code/.
    Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
    Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.
    LinkedIn Profile: http://www.linkedin.com/in/keithoxenrider

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw
  4. #3
  5. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,624
    Rep Power
    4247
    Originally Posted by lasm
    Hi Guys,
    still having a few issues with pointers...
    I came across this expression that obviously works and I can even see what it is doing, but I can not get my head around it.

    for the ARM uC I am using they have this definition:

    #define PB8 (*((volatile unsigned long *) 0x422181A0))

    and then the usage is so:

    PB8 = 1;
    This means, write the value 1 to the memory address 0x422181A0

    Another way to write this is:
    Code:
    volatile unsigned long *ptr;
    ptr = 0x422181A0UL;
    *ptr = 1;
    Does that make sense now?

    As far as the code is concerned, it looks like it is writing to some memory mapped hardware, probably some kind of latch, which is typical of embedded systems.
    Last edited by Scorpions4ever; September 19th, 2012 at 04:45 AM.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2011
    Posts
    21
    Rep Power
    0
    Hi Guys,
    I know what the instructions are doing and the code Scorpions4ever wrote is exactly how I though it would be written.
    What I have never seen is this way of writing this code, is this ANSI-C compliant and if so where would I find more info about it.

    Thanks
    Luis
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    San Francisco Bay
    Posts
    1,939
    Rep Power
    1313
    The code
    Code:
    PB8 = 1;
    expands to
    Code:
    (*((volatile unsigned long *) 0x422181A0)) = 1;
    Let's take this apart:
    Code:
    0x422181A0
    That's just an unsigned integer.
    Code:
    (volatile unsigned long *) 0x422181A0
    That's a type cast: the integer 0x422181A0 is treated as a pointer to a volatile unsigned long integer, and that pointer is the result of that expression.
    Code:
    *((volatile unsigned long *) 0x422181A0)
    Here that pointer is dereferenced. Note that a dereferenced pointer is an "lvalue": it can be assigned to, i.e., it can appear on the left-hand side of an assignment expression, speaking of which:
    Code:
    (*((volatile unsigned long *) 0x422181A0)) = 1;
    This stores the value 1 in the block of memory referenced by the pointer.

    My point is that if you know what an integer literal is, what a type cast is, what a pointer dereference is, and what the assignment operator is, then you already know this syntax (but you may not know that you know).

    Comments on this post

    • lasm agrees : Great clear Explanation
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2011
    Posts
    21
    Rep Power
    0
    Hi Lux Perpetua,
    Thank you for that, this was exactly the clarification I was needing. you are right, I already know all the parts, it was just putting it all together. The key is the casting. My other problem is that normally you would create a variable prt or x to be your pointer, but in this case they are not assigning it to anything and that was confusing me. the key, and please correct me if I am wrong, is the #define expression. with this expression you are not assigning or creating a pointer, you are just replacing, in this case, PB8 with the text "(*((volatile unsigned long *) 0x422181A0))" and that's why this works. I am not actually creating a variable called PB8 which happens to be a pointer, I am just saying that where you see PB8 on my program it should actually read "(*((volatile unsigned long *) 0x422181A0))".
    Please Guys correct me if I am wrong.
    Thank you all so much.
    Best Regards
    Luis
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    San Francisco Bay
    Posts
    1,939
    Rep Power
    1313
    Yes, your interpretation there is correct. The #define directive creates a macro. Macros are expanded during preprocessing, which happens before compilation, and macro expansion is literally textual subsitution. What the compiler sees is "(*((volatile unsigned long *) 0x422181A0))"; it never sees "PB8", which is expanded by the preprocessor before the compiler does anything.

IMN logo majestic logo threadwatch logo seochat tools logo