简体   繁体   English

如何声明易失性结构的指针

[英]how to declare pointer to volatile struct

Let's say I have the following definitions : 假设我有以下定义:

/* 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__));

Now if I acces the register through UART1, everything is fine, but what if I us a pointer to the structure, how should I declare it to specify the whole aera pointed to is volatile ? 现在,如果我通过UART1访问寄存器,那么一切都很好,但是如果我使用一个指向该结构的指针,该如何声明它以指定所指向的整个区域是易失的呢?

volatile UART * hw = &UART1;

Is that ok ? 这可以吗 ?

If you declare 如果您声明

extern volatile UART UART1;

Then any pointer derived from that variable will be of type volatile UART * and as a matter of fact your compiler should issue a warning if you try to assign it to any other type of variable. 然后,从该变量派生的任何指针将属于volatile UART *类型,实际上,如果尝试将其分配给任何其他类型的变量,则编译器应发出警告。

If you wish UART to always be volatile then you can typedef it as such 如果您希望UART总是volatile则可以这样键入def

typedef volatile struct {...} tagUART UART;

Or as unwind said to declare specific fields as volatile 或如放松所说将特定字段声明为volatile

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

The inline use of volatile ie 内联使用volatile

while (*(volatile int *)&a) ;

is discouraged and should only be used for variables that are normally not volatile, but have to be in this context. 不鼓励使用,并且仅应将其用于通常不是易失性的变量,而必须在这种情况下使用。

Another way is to have a union where accessing one version is volatile another is not: 另一种方法是有一个union ,其中访问一个版本是挥发性另一个不是:

union {
    volatile UART volatile_version;
    UART normal;
};

I think that's the wrong way; 我认为那是错误的方式; what if somebody (=you three months later) uses a pointer to USART but forget about the volatile part? 如果有人(=三个月后您)使用指向USART的指针但忘记了volatile部分怎么办?

The proper way is to declare each field as being volatile . 正确的方法是将每个字段声明为volatile It's a bit messy, but better since it captures more of what you're trying to model right there in the code. 有点混乱,但是更好,因为它捕获了您正在代码中尝试建模的更多内容。

You often see a macro such as __IO being used for fields of structures that model hardware registers, and it typically includes volatile in its expansion. 您经常会看到诸如__IO的宏用于对硬件寄存器建模的结构的字段,并且通常在扩展中包括volatile

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM