我正在尝试更改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则不支持。
谢谢。
答案 0 :(得分: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;
答案 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
冲突。你当然可以根据自己的喜好重命名。
答案 2 :(得分:0)
我知道这不是答案,但我没有足够的声誉来编辑这个问题。我希望这可能有助于澄清。如果你从图片中取出所有的宏,Alan_m想要最终得到的是一个匿名联盟,如下所示:
volatile union {
u32 IO0PIN;
u16 IO0PIN_bit;
};
可以像这样引用:
void test( void )
{
IO0PIN = 0x0xAA55AA55;
IO0PIN_bit.P0_5 = 0;
}
这适用于O.K.使用IAR编译器但在VC ++编译器上导致编译器错误
错误C2646:全球匿名联盟 必须声明为静态
请注意,这是来自VS2005,因此它可能与VS2008略有不同。
我认为所有Alan_m的代码都已写入IAR标准,并且必须进行修改才能使用他想要避免使用的命名联合。