Variable like object at specific address

Discussion in 'C++' started by Glenn Møller-Holst, Apr 5, 2008.

  1. Hi!

    Is it possible to transform these macro definitions to a c++/c
    "variable" at specific address? It is going to be used on an ARM-processor:

    #define IOPIN0 (*((volatile unsigned long *) 0xE0028000))
    #define IOSET0 (*((volatile unsigned long *) 0xE0028004))
    #define IODIR0 (*((volatile unsigned long *) 0xE0028008))
    #define IOCLR0 (*((volatile unsigned long *) 0xE002800C))

    to some native C++, C? So it is possible to write:

    unsigned long iopin0 /*some declaration defining iopin0 at the address
    0xE0028000*/;

    Applications:

    iodir0 |= 0x00400000;
    iopin0 = 0x00400000;
    /*some instruction write sequence*/;

    iodir0 &= (~0x00400000);
    /*some instruction read sequence*/;
    x= iopin0; // read pin.

    -

    The purpose is to be able to send the variable (eg. io) as a
    const-parameter:


    typedef struct io_iog_t { // iog: io-group.
    volatile unsigned int pin; // 32 bit.
    volatile unsigned int set;
    volatile unsigned int dir;
    volatile unsigned int clr;
    } io_iog_t;

    typedef struct iopin_t { // iopin: io-consecutive pin group.
    unsigned char pingroup; // 8 bits.
    unsigned char firstpinselected; // 8 bits.
    unsigned int consecutivepinselection; // 32 bits.
    } iopin_t;

    struct io_iog_t iog[3] /* start address 0xE0028000 */;
    const struct iopin_t io= { // Will normally be passed
    pingroup= 0, // to a class or function as const.
    firstpinselected= 5,
    consecutivepinselection= 0x01 };

    Applications:
    iog[io.pingroup].dir &= (~(consecutivepinselection<<io.firstpinselected));
    /*some instruction read sequence*/;
    x= ((iog[io.pingroup].pin)>>io.firstpinselected)&io.consecutivepinselection;

    iog[io.pingroup].dir |= (consecutivepinselection<<io.firstpinselected);
    iog[io.pingroup].pin = (1<<io.firstpinselected);
    /*some instruction write sequence*/;

    regards,

    Glenn
    Glenn Møller-Holst, Apr 5, 2008
    #1
    1. Advertising

  2. "Glenn Møller-Holst" <> wrote in message
    news:ft85d0$7eo$-c.dk...
    : Is it possible to transform these macro definitions to a c++/c
    : "variable" at specific address? It is going to be used on an
    ARM-processor:
    :
    : #define IOPIN0 (*((volatile unsigned long *) 0xE0028000))
    : #define IOSET0 (*((volatile unsigned long *) 0xE0028004))
    : #define IODIR0 (*((volatile unsigned long *) 0xE0028008))
    : #define IOCLR0 (*((volatile unsigned long *) 0xE002800C))
    :
    : to some native C++, C? So it is possible to write:
    :
    : unsigned long iopin0 /*some declaration defining iopin0 at the address
    : 0xE0028000*/;

    There are some compiler-specific extensions that allow you to do so.
    You could also try writing:
    volatile unsigned long& iopin0 = *((volatile unsigned
    long*)0xE0028000);
    This can work as well with a struct / other variable type.

    This said, in this type of context, I often prefer to focus on a
    slightly higer-level level of encapsulation. (sometimes a
    vendor-provided
    header exists with such #define-s, and you want to avoid rewriting
    them).
    As long as these #define-s are well-encapsulated in a single file
    (e.g. a module providing functions for sending/reading complete
    messages), I would not worry too much about getting rid of them.


    Regards -Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
    Brainbench MVP for C++ <> http://www.brainbench.com
    Ivan Vecerina, Apr 5, 2008
    #2
    1. Advertising

  3. On 2008-04-05 17:20, Glenn Møller-Holst wrote:
    > Hi!
    >
    > Is it possible to transform these macro definitions to a c++/c
    > "variable" at specific address? It is going to be used on an ARM-processor:
    >
    > #define IOPIN0 (*((volatile unsigned long *) 0xE0028000))
    > #define IOSET0 (*((volatile unsigned long *) 0xE0028004))
    > #define IODIR0 (*((volatile unsigned long *) 0xE0028008))
    > #define IOCLR0 (*((volatile unsigned long *) 0xE002800C))
    >
    > to some native C++, C? So it is possible to write:


    Since it seems like you are working quite close to the hardware I
    suppose that you are quite familiar with pointers, so why not treat it
    as one (since it is one)? You might want to create a typedef if you are
    going to pass it around a lot.

    unsigned long * const IoPin0 = (unsigned long*)0x00400000;



    Or you could create a wrapper class, and overload common operations,
    such as =, |=, etc., but that might require more effort than it is worth.

    --
    Erik Wikströmö
    Erik Wikström, Apr 5, 2008
    #3
  4. Thanks to both of you. I will try it them.

    regards,

    Glenn
    Glenn Møller-Holst, Apr 5, 2008
    #4
  5. Re: Array(variable) like object at specific address

    Hi!

    I am still having some problems declaring an array:

    static const int grpidxfirst= 0;
    static const int grpidxlast= 3;

    // Works:
    volatile unsigned long& iopin1 = *((volatile unsigned long*)0xE0028010);

    // Array declaration do not work - can it be made ok?:
    volatile io_iog_t & io[3] = *((io_iog_t*)0xE0028000);

    // This array declaration do not work either - can it be made ok?:
    volatile int & io[15] = *((int*)0xE0028000);

    It would be useful to be able to use that kind of array.

    regards,

    Glenn

    -

    Declaration of io_iog_t:

    Glenn Møller-Holst wrote:
    > Hi!
    >
    > Is it possible to transform these macro definitions to a c++/c
    > "variable" at specific address? It is going to be used on an ARM-processor:
    >
    > #define IOPIN0 (*((volatile unsigned long *) 0xE0028000))
    > #define IOSET0 (*((volatile unsigned long *) 0xE0028004))
    > #define IODIR0 (*((volatile unsigned long *) 0xE0028008))
    > #define IOCLR0 (*((volatile unsigned long *) 0xE002800C))
    >
    > to some native C++, C? So it is possible to write:
    >
    > unsigned long iopin0 /*some declaration defining iopin0 at the address
    > 0xE0028000*/;
    >
    > Applications:
    >
    > iodir0 |= 0x00400000;
    > iopin0 = 0x00400000;
    > /*some instruction write sequence*/;
    >
    > iodir0 &= (~0x00400000);
    > /*some instruction read sequence*/;
    > x= iopin0; // read pin.
    >
    > -
    >
    > The purpose is to be able to send the variable (eg. io) as a
    > const-parameter:
    >
    >
    > typedef struct io_iog_t { // iog: io-group.
    > volatile unsigned int pin; // 32 bit.
    > volatile unsigned int set;
    > volatile unsigned int dir;
    > volatile unsigned int clr;
    > } io_iog_t;
    >
    > typedef struct iopin_t { // iopin: io-consecutive pin group.
    > unsigned char pingroup; // 8 bits.
    > unsigned char firstpinselected; // 8 bits.
    > unsigned int consecutivepinselection; // 32 bits.
    > } iopin_t;
    >
    > struct io_iog_t iog[3] /* start address 0xE0028000 */;
    > const struct iopin_t io= { // Will normally be passed
    > pingroup= 0, // to a class or function as const.
    > firstpinselected= 5,
    > consecutivepinselection= 0x01 };
    >
    > Applications:
    > iog[io.pingroup].dir &= (~(consecutivepinselection<<io.firstpinselected));
    > /*some instruction read sequence*/;
    > x=
    > ((iog[io.pingroup].pin)>>io.firstpinselected)&io.consecutivepinselection;
    >
    > iog[io.pingroup].dir |= (consecutivepinselection<<io.firstpinselected);
    > iog[io.pingroup].pin = (1<<io.firstpinselected);
    > /*some instruction write sequence*/;
    >
    > regards,
    >
    > Glenn
    Glenn Møller-Holst, Apr 6, 2008
    #5
  6. Re: Array(variable) like object at specific address

    Glenn Møller-Holst wrote:

    > Hi!
    >
    > I am still having some problems declaring an array:
    >
    > static const int grpidxfirst= 0;
    > static const int grpidxlast= 3;
    >
    > // Works:
    > volatile unsigned long& iopin1 = *((volatile unsigned long*)0xE0028010);
    >
    > // Array declaration do not work - can it be made ok?:
    > volatile io_iog_t & io[3] = *((io_iog_t*)0xE0028000);
    >
    > // This array declaration do not work either - can it be made ok?:
    > volatile int & io[15] = *((int*)0xE0028000);
    >
    > It would be useful to be able to use that kind of array.


    Why don't you declare it as a pointer? You can then access it like an array:

    struct io_iog_t {
    volatile unsigned int pin;
    volatile unsigned int set;
    volatile unsigned int dir;
    volatile unsigned int clr;
    };

    io_iog_t * const io = (io_iog_t*)0xE0028000;

    int f()
    {
    io[0].set = 5;
    return io[3].clr;
    }

    Gives the following code with g++4.2 -O3 -fomit-frame-pointer:
    _Z1fv:
    ..LFB2:
    movl $5, -536707068
    movl -536707012, %eax
    ret

    Just as you wanted?

    Also note that in C++ you can lose the typedef and you probably shouldn't
    use "unsigned int" and "unsigned char" but the (C99?) uint32_t and uint8_t
    data types. You might also have to tell the compiler to not do any packing,
    but this is highly compiler specific AFAIK.

    HTH.
    Paul Brettschneider, Apr 6, 2008
    #6
  7. Re: Array(variable) like object at specific address

    Paul Brettschneider wrote:

    > Glenn Møller-Holst wrote:
    >
    >> Hi!
    >>
    >> I am still having some problems declaring an array:
    >>
    >> static const int grpidxfirst= 0;
    >> static const int grpidxlast= 3;
    >>
    >> // Works:
    >> volatile unsigned long& iopin1 = *((volatile unsigned long*)0xE0028010);
    >>
    >> // Array declaration do not work - can it be made ok?:
    >> volatile io_iog_t & io[3] = *((io_iog_t*)0xE0028000);
    >>
    >> // This array declaration do not work either - can it be made ok?:
    >> volatile int & io[15] = *((int*)0xE0028000);
    >>
    >> It would be useful to be able to use that kind of array.

    >
    > Why don't you declare it as a pointer? You can then access it like an
    > array:
    >
    > struct io_iog_t {
    > volatile unsigned int pin;
    > volatile unsigned int set;
    > volatile unsigned int dir;
    > volatile unsigned int clr;
    > };
    >
    > io_iog_t * const io = (io_iog_t*)0xE0028000;
    >
    > int f()
    > {
    > io[0].set = 5;
    > return io[3].clr;
    > }
    >
    > Gives the following code with g++4.2 -O3 -fomit-frame-pointer:
    > _Z1fv:
    > .LFB2:
    > movl $5, -536707068
    > movl -536707012, %eax
    > ret
    >
    > Just as you wanted?
    >
    > Also note that in C++ you can lose the typedef and you probably shouldn't
    > use "unsigned int" and "unsigned char" but the (C99?) uint32_t and uint8_t
    > data types. You might also have to tell the compiler to not do any
    > packing, but this is highly compiler specific AFAIK.


    padding not packing. As always too fast on the "send" button. :(
    Paul Brettschneider, Apr 6, 2008
    #7
  8. Re: Array(variable) like object at specific address

    Paul Brettschneider wrote:
    ....
    > Why don't you declare it as a pointer? You can then access it like an array:
    >
    > struct io_iog_t {
    > volatile unsigned int pin;
    > volatile unsigned int set;
    > volatile unsigned int dir;
    > volatile unsigned int clr;
    > };
    >
    > io_iog_t * const io = (io_iog_t*)0xE0028000;
    >
    > int f()
    > {
    > io[0].set = 5;
    > return io[3].clr;
    > }
    >
    > Gives the following code with g++4.2 -O3 -fomit-frame-pointer:
    > _Z1fv:
    > .LFB2:
    > movl $5, -536707068
    > movl -536707012, %eax
    > ret
    >
    > Just as you wanted?
    >
    > Also note that in C++ you can lose the typedef and you probably shouldn't
    > use "unsigned int" and "unsigned char" but the (C99?) uint32_t and uint8_t
    > data types. You might also have to tell the compiler to not do any packing,
    > but this is highly compiler specific AFAIK.
    >
    > HTH.


    Hi Paul

    It nearly worked in the GCC compiler:

    typedef struct iog_t { // Digital io-consecutive pin group.
    volatile tu32 pin;
    volatile tu32 set;
    volatile tu32 dir;
    volatile tu32 clr;
    } iog_t;

    static const int grpidxfirst= 0;
    static const int grpidxlast= 3;

    iog_t* const io = (iog_t*)0xE0028000;
    ....
    tu32 x= io[0].pin;
    85: io[0].dir=1;

    Compiler result:

    pin.hpp:85: error: expected constructor, destructor, or type conversion
    before '.' token

    regards,

    Glenn
    Glenn Møller-Holst, Apr 6, 2008
    #8
  9. Re: Array(variable) like object at specific address [ GCC version]

    Glenn Møller-Holst wrote:
    > Paul Brettschneider wrote:
    > ...
    >> Why don't you declare it as a pointer? You can then access it like an
    >> array:
    >>
    >> struct io_iog_t {
    >> volatile unsigned int pin;
    >> volatile unsigned int set;
    >> volatile unsigned int dir;
    >> volatile unsigned int clr;
    >> };
    >>
    >> io_iog_t * const io = (io_iog_t*)0xE0028000;
    >>
    >> int f()
    >> {
    >> io[0].set = 5;
    >> return io[3].clr;
    >> }
    >>
    >> Gives the following code with g++4.2 -O3 -fomit-frame-pointer:
    >> _Z1fv:
    >> .LFB2:
    >> movl $5, -536707068
    >> movl -536707012, %eax
    >> ret
    >>
    >> Just as you wanted?
    >>
    >> Also note that in C++ you can lose the typedef and you probably shouldn't
    >> use "unsigned int" and "unsigned char" but the (C99?) uint32_t and
    >> uint8_t
    >> data types. You might also have to tell the compiler to not do any
    >> packing,
    >> but this is highly compiler specific AFAIK.
    >>
    >> HTH.

    >
    > Hi Paul
    >
    > It nearly worked in the GCC compiler:
    >
    > typedef struct iog_t { // Digital io-consecutive pin group.
    > volatile tu32 pin;
    > volatile tu32 set;
    > volatile tu32 dir;
    > volatile tu32 clr;
    > } iog_t;
    >
    > static const int grpidxfirst= 0;
    > static const int grpidxlast= 3;
    >
    > iog_t* const io = (iog_t*)0xE0028000;
    > ...
    > tu32 x= io[0].pin;
    > 85: io[0].dir=1;
    >
    > Compiler result:
    >
    > pin.hpp:85: error: expected constructor, destructor, or type conversion
    > before '.' token
    >
    > regards,
    >
    > Glenn


    The Compiler is:

    #arm-elf-gcc -dumpversion
    4.2.0
    #arm-elf-gcc -dumpmachine
    arm-elf

    regards,

    Glenn
    Glenn Møller-Holst, Apr 6, 2008
    #9
  10. Re: Array(variable) like object at specific address

    Hi,

    Glenn Møller-Holst wrote:

    > Paul Brettschneider wrote:
    > ...
    >> Why don't you declare it as a pointer? You can then access it like an
    >> array:
    >>
    >> struct io_iog_t {
    >> volatile unsigned int pin;
    >> volatile unsigned int set;
    >> volatile unsigned int dir;
    >> volatile unsigned int clr;
    >> };
    >>
    >> io_iog_t * const io = (io_iog_t*)0xE0028000;
    >>
    >> int f()
    >> {
    >> io[0].set = 5;
    >> return io[3].clr;
    >> }
    >>
    >> Gives the following code with g++4.2 -O3 -fomit-frame-pointer:
    >> _Z1fv:
    >> .LFB2:
    >> movl $5, -536707068
    >> movl -536707012, %eax
    >> ret
    >>
    >> Just as you wanted?
    >>
    >> Also note that in C++ you can lose the typedef and you probably shouldn't
    >> use "unsigned int" and "unsigned char" but the (C99?) uint32_t and
    >> uint8_t data types. You might also have to tell the compiler to not do
    >> any packing, but this is highly compiler specific AFAIK.
    >>
    >> HTH.

    >
    > Hi Paul
    >
    > It nearly worked in the GCC compiler:
    >
    > typedef struct iog_t { // Digital io-consecutive pin group.
    > volatile tu32 pin;
    > volatile tu32 set;
    > volatile tu32 dir;
    > volatile tu32 clr;
    > } iog_t;
    >
    > static const int grpidxfirst= 0;
    > static const int grpidxlast= 3;
    >
    > iog_t* const io = (iog_t*)0xE0028000;
    > ...
    > tu32 x= io[0].pin;
    > 85: io[0].dir=1;
    >
    > Compiler result:
    >
    > pin.hpp:85: error: expected constructor, destructor, or type conversion
    > before '.' token


    Are you doing this *inside* a function? Because there it definitely works
    for me. May I suggest you post a minimal but complete example which
    produces this error? Maybe I misunderstand what you're trying to achieve...

    Here is an example that compiles for me (btw, I'm absolutely not sure about
    the use of volatile, it might very well not be enough):

    #include <inttypes.h>

    struct io_iog_t {
    volatile uint32_t pin;
    volatile uint32_t set;
    volatile uint32_t dir;
    volatile uint32_t clr;
    };

    io_iog_t * const io = (io_iog_t*)0xE0028000;

    int f()
    {
    io[0].set = 5;
    io[0].dir = 1;
    return io[3].clr;
    }
    Paul Brettschneider, Apr 6, 2008
    #10
  11. Re: Array(variable) like object at specific address

    Paul Brettschneider wrote:
    ....
    > Are you doing this *inside* a function? Because there it definitely works
    > for me. May I suggest you post a minimal but complete example which
    > produces this error? Maybe I misunderstand what you're trying to achieve...
    >
    > Here is an example that compiles for me (btw, I'm absolutely not sure about
    > the use of volatile, it might very well not be enough):

    ....

    Hi Paul

    Thank for your help. I just did a silly mistake. It works now.

    kind regards,

    Glenn
    Glenn Møller-Holst, Apr 6, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Casey
    Replies:
    10
    Views:
    709
    Dan Cernat
    Oct 20, 2004
  2. Ramesh Tharma
    Replies:
    3
    Views:
    356
    Kristo
    Jun 8, 2005
  3. =?Utf-8?B?SmF2?=

    Is ViwState Page-Specific or UserControl-Specific

    =?Utf-8?B?SmF2?=, Aug 16, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    530
    =?Utf-8?B?SmF2?=
    Aug 16, 2006
  4. Patrick Kowalzick
    Replies:
    5
    Views:
    470
    Patrick Kowalzick
    Mar 14, 2006
  5. mazdotnet
    Replies:
    2
    Views:
    396
    Alexey Smirnov
    Oct 2, 2009
Loading...

Share This Page