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

发布于 2024-08-29 21:00:11 字数 1335 浏览 3 评论 0原文

我正在尝试更改 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不支持。

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忘东忘西忘不掉你 2024-09-05 21:00:11

好吧,伙计们,这就是最终为我工作的内容:

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

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;
め七分饶幸 2024-09-05 21:00:11

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

#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 发生冲突。您当然可以根据自己的喜好重命名。

The usual way of doing this is with a macro that just casts 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)

Now IO0PIN can be used just as you described. However, note that I had to rename the internal field and type name to avoid conflicting with the macro name IO0PIN. You can of course rename things to your liking.

自在安然 2024-09-05 21:00:11

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

volatile union {
   u32 IO0PIN;
   u16 IO0PIN_bit;
};

可以像这样引用:

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

This Works OK with the IAR Compiler but Causes a Compiler Error on the VC++ Compiler

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

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

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

I know this isn't an answer but I don't have enough reputation to edit the question. I hope this might be helpful for clarification. If you take all of the macros out of the picture, what Alan_m wants to end up with is an anonymous union like the following:

volatile union {
   u32 IO0PIN;
   u16 IO0PIN_bit;
};

That can be referenced like this:

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

This works O.K. with the IAR compiler but causes a compiler error on the VC++ compiler

error C2646: global anonymous unions
must be declared static

Note that this is from VS2005 so it might be slightly different than VS2008.

I would imagine all of Alan_m's code is already written to IAR standards and would have to be modified to use named unions which he wants to avoid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文