Anonymous join definition / declaration in a macro GNU vs VS2008
I am trying to change the specific IAR header file for lpc2138 so that it can compile with Visual Studio 2008 (to enable compatible unit testing).
My problem is converting register definitions to hardware independent (not by memory address)
"IAR-safe macro":
#define __IO_REG32_BIT(NAME, ADDRESS, ATTRIBUTE, BIT_STRUCT) \
volatile __no_init ATTRIBUTE union \
{ \
unsigned long NAME; \
BIT_STRUCT NAME ## _bit; \
} @ ADDRESS
//declaration
//(where __gpio0_bits is a structure that names
//each of the 32 bits as P0_0, P0_1, etc)
__IO_REG32_BIT(IO0PIN,0xE0028000,__READ_WRITE,__gpio0_bits);
//usage
IO0PIN = 0x0xAA55AA55;
IO0PIN_bit.P0_5 = 0;
This is my comparable "device independent" code:
#define __IO_REG32_BIT(NAME, BIT_STRUCT)\
volatile union \
{ \
unsigned long NAME; \
BIT_STRUCT NAME##_bit; \
} NAME;
//declaration
__IO_REG32_BIT(IO0PIN,__gpio0_bits);
//usage
IO0PIN.IO0PIN = 0xAA55AA55;
IO0PIN.IO0PIN_bit.P0_5 = 1;
This compiles and works, but it is quite clear that my "hardware independent" usage is not the same as "IAR-safe" usage.
How do I change my macro so that I can use IO0PIN in the same way as in IAR? I believe this is a simple anonymous union, but several attempts and options have been unsuccessful. Perhaps the GNU IAR compiler supports anonymous joins, while vs2008 does not.
Thanks.
a source to share
Ok people here, what ended up working for me:
#define __IO_REG32_BIT(NAME, BIT_STRUCT)\
volatile union\
{\
unsigned long NAME;\
BIT_STRUCT NAME##_bit;\
} NAME##_type;
__IO_REG32_BIT(IO0PIN,__gpio0_bits);
#define IO0PIN IO0PIN_type.IO0PIN
#define IO0PIN_bit IO0PIN_type.IO0PIN_bit
Now I can use the following in my code for unit testing:
IO0PIN = 0xFFFFFFFF;
IO0PIN_bit.P0_5 = 1;
And the preprocessor will replace it with:
IO0PIN_type.IO0PIN = 0xFFFFFFFF;
IO0PIN_type.IO0PIN_bit.P0_5 = 1;
a source to share
The usual way to do this is with a macro that simply assigns the desired address to the appropriate type:
#define __IO_REG32_BIT(NAME, BIT_STRUCT) \
typedef volatile union \
{ \
unsigned long NAME##_value: \
BIT_STRUCT NAME##_bit; \
} NAME##_type
__IO_REG32_BIT(IO0PIN, __gpio0_bits);
#define IO0PIN (*(IO0PIN_type *)0xE0028000)
IO0PIN
Can now be used in the same way as described. Note, however, that I had to rename the internal field and type name to avoid conflict with the macro name IO0PIN
. You can of course rename things to your liking.
a source to share
I know this is not an answer, but I don't have enough reputation to edit the question. Hope this can be helpful for clarification. If you grab all the macros from the image, what Alan_m wants is an anonymous union, as shown below:
volatile union {
u32 IO0PIN;
u16 IO0PIN_bit;
};
You can do it like this:
void test( void )
{
IO0PIN = 0x0xAA55AA55;
IO0PIN_bit.P0_5 = 0;
}
This works O.K. with IAR compiler, but raises compiler error in VC ++ compiler
error C2646: global anonymous joins must be declared static
Note that this is from VS2005, so it may be slightly different from VS2008.
I would suggest that all of Alan_m's code is already written into the IAR standards and needs to be modified to use the named unions it wants to avoid.
a source to share