cmacrosunionsanonymous-types

Anonymous union definition/declaration in a macro GNU vs VS2008


I am attempting to alter an IAR specific header file for a lpc2138 so it can compile with Visual Studio 2008 (to enable compatible unit testing).

My problem involves converting register definitions to be hardware independent (not at a memory address)

The "IAR-safe macro" is:

#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 "hardware 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 quite obviously my "hardware independent" usage does not match the "IAR-safe" usage.

How do I alter my macro so I can use IO0PIN the same way I do in IAR? I feel this is a simple anonymous union matter but multiple attempts and variants have proven unsuccessful. Maybe the IAR GNU compiler supports anonymous unions and vs2008 does not.

Thank you.


Solution

  • Ok folks here's 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;