How to associate a name with a structure element at compile time? 
Author Message
 How to associate a name with a structure element at compile time?

Greetings all -
I'm developing a piece of embedded code in which I need to be able to
access a member of
a structure by name.  The structure is overlaid onto my hardware.  For
example:

typedef struct xyz {
    unsigned int reg_a;
    unsigned int reg_b;

Quote:
} xyz_t;

xyz_t *xyz_p = (xyz_t *) 0x12345678;

So now I can do things like xyz_p->reg_a = 4 and that gets written to
the hardware.

So far so good.  What I'd like to be able to do is set up an array which
maps english names to
hardware addresses.   I'd like to be able to do this statically at
compile time.  For example:

typedef struct {
   const char *reg_name_p;
   unsigned int reg_addr;

Quote:
} reg_assoc_t;

reg_assoc_t reg_assoc[] = {
   {"register A",                 (unsigned int)&xyz_p->reg_a},  /* this
fails since the address is non-constant */
   {0, 0},

Quote:
};

Does anyone have any suggestions on how to accomplish the hardware
access and name mapping so
it can be done at copile time?

Thanks!

keith
--



Sun, 25 May 2003 03:00:00 GMT  
 How to associate a name with a structure element at compile time?
On 06 Dec 2000 20:58:13 GMT, Keith Ou{*filter*}er

Quote:

>Greetings all -
>I'm developing a piece of embedded code in which I need to be able to
>access a member of
>a structure by name.  The structure is overlaid onto my hardware.  For
>example:

>typedef struct xyz {
>    unsigned int reg_a;
>    unsigned int reg_b;
>} xyz_t;

>xyz_t *xyz_p = (xyz_t *) 0x12345678;

>So now I can do things like xyz_p->reg_a = 4 and that gets written to
>the hardware.

I wouldn't suggest doing that.  The compiler is free to add padding,
so reg_b might not end up where you want it to...

- Show quoted text -

Quote:

>So far so good.  What I'd like to be able to do is set up an array which
>maps english names to
>hardware addresses.   I'd like to be able to do this statically at
>compile time.  For example:

>typedef struct {
>   const char *reg_name_p;
>   unsigned int reg_addr;
>} reg_assoc_t;

>reg_assoc_t reg_assoc[] = {
>   {"register A",                 (unsigned int)&xyz_p->reg_a},  /* this
>fails since the address is non-constant */
>   {0, 0},
>};

>Does anyone have any suggestions on how to accomplish the hardware
>access and name mapping so
>it can be done at copile time?

typedef struct xyz {
    unsigned int reg_a;
    unsigned int reg_b;

Quote:
} xyz_t;

typedef struct {
   const char *reg_name_p;
   unsigned int reg_addr;

Quote:
} reg_assoc_t;

#define XYZ     ((xyz_t *)0x12345678)

reg_assoc_t reg_assoc[] = {
   {"register A",       (unsigned int)&XYZ->reg_a},
   {0, 0},

Quote:
};

Not pretty, but gcc takes it...

Regards,

I Don't Do Windoze
--



Mon, 26 May 2003 14:56:24 GMT  
 How to associate a name with a structure element at compile time?
On 06 Dec 2000 20:58:13 GMT, Keith Ou{*filter*}er

Quote:
> Greetings all -
> I'm developing a piece of embedded code in which I need to be able to
> access a member of
> a structure by name.  The structure is overlaid onto my hardware.  For
> example:

> typedef struct xyz {
>     unsigned int reg_a;
>     unsigned int reg_b;
> } xyz_t;

> xyz_t *xyz_p = (xyz_t *) 0x12345678;

> So now I can do things like xyz_p->reg_a = 4 and that gets written to
> the hardware.

> So far so good.  What I'd like to be able to do is set up an array which
> maps english names to
> hardware addresses.   I'd like to be able to do this statically at
> compile time.  For example:

> typedef struct {
>    const char *reg_name_p;
>    unsigned int reg_addr;

This member has the wrong type, it should be:

     unsigned int *reg_addr;

But to make it work easily try:

     void *reg_addr;

Quote:
> } reg_assoc_t;

> reg_assoc_t reg_assoc[] = {
>    {"register A",                 (unsigned int)&xyz_p->reg_a},  /* this
> fails since the address is non-constant */
>    {0, 0},
> };

> Does anyone have any suggestions on how to accomplish the hardware
> access and name mapping so
> it can be done at copile time?

> Thanks!

> keith

{"register A", (void *)0x12345678 },
{"register B", (char *)0x12345678 + offsetof(xyz_t, reg_b)},

....assuming you change the definition of reg_addr to a pointer to
void, which is a better choice than stuffing it into an unsigned int
anyway.

Of course the pointers you get are implementation-defined, and the
result of dereferencing them undefined.

Jack Klein
--
Home: http://www.*-*-*.com/
--



Mon, 26 May 2003 14:56:50 GMT  
 How to associate a name with a structure element at compile time?
Quote:

> typedef struct xyz {
>     unsigned int reg_a;
>     unsigned int reg_b;
> } xyz_t;

> xyz_t *xyz_p = (xyz_t *) 0x12345678;

> So now I can do things like xyz_p->reg_a = 4 and that gets written to
> the hardware.

> So far so good.  What I'd like to be able to do is set up an array which
> maps english names to
> hardware addresses.   I'd like to be able to do this statically at
> compile time.  [...]
> Does anyone have any suggestions on how to accomplish the hardware
> access and name mapping so
> it can be done at copile time?

There are multiple ways to achieve this, in your example code,
some double indirection would be the best IMHO.

  typedef struct {
     const char *reg_name_p;
-    unsigned int reg_addr;
+    void**       reg_base;
+    unsigned int reg_offs;
  } reg_assoc_t;

  reg_assoc_t reg_assoc[] = {
-    {"register A",                 (unsigned int)&xyz_p->reg_a},  
+    {"register A",      &xyz_p,          offsetof(xyz_t, reg_a) },
     {0, 0},
  };

+ set_function (char* name, int value)
+ {
+      reg_assoc_t* reg = lookup (reg_assoc, name);
+      assert(reg->reg_base && *reg->reg_base);
+      *(int*)((*reg->reg_base)+reg->reg_offs) = value;
+ }
+ get_function (char* name)
+ {
+      reg_assoc_t* reg = lookup (reg_assoc, name);
+      assert(reg->reg_base && *reg->reg_base);
+      return *(int*)((*reg->reg_base)+reg->reg_offs);
+ }

BEWARE! The code example is far from perfect. In most of the code
that I have seen, it did *not* stop at static-pointer+offset, and it
did not stop at just one table. If your code is not *very* special
and a one-shot product, I do strongly suggest to create a method
table and a (static?)-linked list of reg_assoc-sections. In linux
kernel it is generally called "_operations", it's simply good style...

struct /* method table a.k.a. reg_assoc-item-class */
{
    int (*set)(reg_assoc_t*, int value);
    int (*get)(reg_assoc_t*);

Quote:
} int_operations = { set_function, get_function };

  reg_assoc_t reg_assoc[] = {
+    {"register A",      &xyz_p,          offsetof(xyz_t, reg_a) },
+    {"register A",      &xyz_p,          offsetof(xyz_t, reg_a),   &int_operations },
     {0, 0},
  };
+ set_int (char* name, int value)
+ {
+      reg_assoc_t* reg = lookup (reg_assoc, name);
+      assert (reg->op && reg->op->set);
+      reg->op->set(reg, value);
+ }

This style leaves room for future extensions, with much more complicated
forms of indirections, or simply some replacement-operations that do
debugging-printf's, malloc-checking, and all other kinds of neat stuff,
e.g.
+    {"register A",      &xyz_p,          offsetof(xyz_t, reg_a),   &int_operations },
+    {"register B",      &xyz_p,          offsetof(xyz_t, reg_a),   &debug_int_operations },

cheers,
-- guido                                Edel sei der Mensch, hilfreich und gut

--



Mon, 26 May 2003 14:57:06 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. How do you name table/structure elements?

2. making pointers to structure elements using array elements

3. Accessing structure fields by name at run time

4. Allocating/DeAllocating Memory associated to an array of structures

5. epen different documents without using the associated program name

6. Associating a Structure w

7. Determining type at run-time or compile-time

8. sizeof operator execution - ? run time/compile time

9. Looking for a time function/code to add 1 second to time structure

10. sizeof an element of a structure

11. Help with structure element casting required

12. printing structure elements with MACRO

 

 
Powered by phpBB® Forum Software