宏 GNU 与 VS2008 中的匿名联合定义/声明

问题描述 投票:0回答:3

我正在尝试更改 lpc2138 的 IAR 特定头文件,以便它可以使用 Visual Studio 2008 进行编译(以启用兼容的单元测试)。

我的问题涉及将寄存器定义转换为与硬件无关的(不在内存地址)

“IAR 安全宏”是:

#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;

这是我的类似“硬件独立”代码:

#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;

这可以编译并工作,但很明显我的“硬件独立”用法与“IAR安全”用法不匹配。

如何更改宏以便可以像在 IAR 中一样使用 IO0PIN?我觉得这是一个简单的匿名工会问题,但多次尝试和变体都被证明是不成功的。 也许 IAR GNU 编译器支持匿名联合而 vs2008 不支持。

谢谢你。

c macros unions anonymous-types
3个回答
1
投票

好吧,伙计们,这就是最终对我有用的东西:

#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

现在我可以在代码中使用以下内容进行单元测试:

IO0PIN = 0xFFFFFFFF;
IO0PIN_bit.P0_5 = 1;

预处理器会将其替换为:

IO0PIN_type.IO0PIN = 0xFFFFFFFF;
IO0PIN_type.IO0PIN_bit.P0_5 = 1;

0
投票

通常的方法是使用宏,将所需的地址转换为适当的类型:

#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
可以按照您所描述的那样使用。 但是,请注意,我必须重命名内部字段和类型名称,以避免与宏名称冲突
IO0PIN
。 您当然可以根据自己的喜好重命名。


0
投票

我知道这不是答案,但我没有足够的声誉来编辑问题。 我希望这可能有助于澄清。 如果您将所有宏从图片中删除,Alan_m 最终想要得到的是如下所示的匿名联合:

volatile union {
   u32 IO0PIN;
   u16 IO0PIN_bit;
};

可以这样引用:

void test( void )
{
   IO0PIN = 0x0xAA55AA55;
   IO0PIN_bit.P0_5 = 0;
}

这工作正常。使用 IAR 编译器,但在 VC++ 编译器上会导致编译器错误

错误 C2646:全局匿名联合 必须声明为静态

请注意,这是来自 VS2005,因此可能与 VS2008 略有不同。

我想 Alan_m 的所有代码都已经按照 IAR 标准编写,并且必须进行修改才能使用他想要避免的命名联合。

© www.soinside.com 2019 - 2024. All rights reserved.