如何声明指向volatile结构的指针

时间:2013-11-29 14:39:32

标签: c

我们说我有以下定义:

/* Generic structure of entire SFR area for each UART module */
typedef struct tagUART {
        unsigned int uxmode;
        unsigned int uxsta;
        unsigned int uxtxreg;
        unsigned int uxrxreg;
        unsigned int uxbrg;
} UART, *PUART;



/* SFR blocks for each UART module */
extern volatile UART UART1 __attribute__((__sfr__));
extern volatile UART UART2 __attribute__((__sfr__));

现在如果我通过UART1访问寄存器,一切都很好,但是如果我使用指向结构的指针,我应该如何声明它指定整个指向的aela是不稳定的?

volatile UART * hw = &UART1;

可以吗?

2 个答案:

答案 0 :(得分:3)

如果您声明

extern volatile UART UART1;

然后从该变量派生的任何指针都将是volatile UART *类型,事实上,如果您尝试将其分配给任何其他类型的变量,您的编译器应发出警告。

如果您希望UART永远是volatile,那么您可以输入这样的

typedef volatile struct {...} tagUART UART;

或者,因为展开声明将特定字段声明为易失性

typedef struct tagUART {
        volatile unsigned int uxmode;
        unsigned int uxsta;
        volatile unsigned int uxtxreg;
        unsigned int uxrxreg;
        unsigned int uxbrg;
} UART, *PUART;

内联使用volatile

while (*(volatile int *)&a) ;
不建议使用

,并且只应该用于通常不易变的变量,但必须在此上下文中。

另一种方法是拥有union,其中访问一个版本是volatile,而另一个版本不是:

union {
    volatile UART volatile_version;
    UART normal;
};

答案 1 :(得分:1)

我认为这是错误的方式;如果某人(=你三个月后)使用指向USART的指针而忘记volatile部分会怎么样?

正确的方法是将每个字段声明为volatile。它有点乱,但更好,因为它捕获了你在代码中想要建模的更多东西。

您经常会看到__IO这样的宏用于建模硬件寄存器的结构字段,并且在其扩展中通常包含volatile