Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Variable like object at specific address

Reply
Thread Tools

Variable like object at specific address

 
 
Glenn Mřller-Holst
Guest
Posts: n/a
 
      04-05-2008
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 *) 0xE002800)
#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.consecutivepinselec tion;

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

regards,

Glenn
 
Reply With Quote
 
 
 
 
Ivan Vecerina
Guest
Posts: n/a
 
      04-05-2008
"Glenn Mřller-Holst" <(E-Mail Removed)> wrote in message
news:ft85d0$7eo$(E-Mail Removed)-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 *) 0xE002800)
: #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

 
Reply With Quote
 
 
 
 
Erik Wikström
Guest
Posts: n/a
 
      04-05-2008
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 *) 0xE002800)
> #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ö
 
Reply With Quote
 
Glenn Mřller-Holst
Guest
Posts: n/a
 
      04-05-2008
Thanks to both of you. I will try it them.

regards,

Glenn
 
Reply With Quote
 
Glenn Mřller-Holst
Guest
Posts: n/a
 
      04-06-2008
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 *) 0xE002800)
> #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.consecutivepinselec tion;
>
> iog[io.pingroup].dir |= (consecutivepinselection<<io.firstpinselected);
> iog[io.pingroup].pin = (1<<io.firstpinselected);
> /*some instruction write sequence*/;
>
> regards,
>
> Glenn

 
Reply With Quote
 
Paul Brettschneider
Guest
Posts: n/a
 
      04-06-2008
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.
 
Reply With Quote
 
Paul Brettschneider
Guest
Posts: n/a
 
      04-06-2008
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.
 
Reply With Quote
 
Glenn Møller-Holst
Guest
Posts: n/a
 
      04-06-2008
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
 
Reply With Quote
 
Glenn Møller-Holst
Guest
Posts: n/a
 
      04-06-2008
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
 
Reply With Quote
 
Paul Brettschneider
Guest
Posts: n/a
 
      04-06-2008
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;
}

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
get object from its object-specific class? Thomas Hafner Ruby 15 03-22-2008 08:30 AM
object-like macro used like function-like macro Patrick Kowalzick C++ 5 03-14-2006 03:30 PM
Object creation - Do we really need to create a parent for a derieved object - can't the base object just point to an already created base object jon wayne C++ 9 09-22-2005 02:06 AM
create an object into a specific address Ramesh Tharma C++ 3 06-08-2005 03:35 PM
Reading specific memory address into variable David Casey C++ 10 10-20-2004 07:25 PM



Advertisments