2015-07-10 69 views
4

我有我使用在我的嵌入的C程序的简单FIFO环形缓冲器队列(使用TI的C28x C/C++编译器,其非常类似于GCC为C89没有扩展)。 数据被中断队列推入并弹出,所以队列需要变化。不透明指针到易失性结构

我,通过声明使得队列用户的队列是否为易挥发或不(我想在几个项目具有不同的用途使用本)选择使用挥发性执行队列代码本身没有在使用中处理一个易失性队列对象,而不是在实现中将队列对象本身定义为volatile。

在que.c

即:

struct QUE_Obj { /* Object & members are not defined as volatile. */ 
    void * data; 
    uint16_t capacity; 
    uint16_t head; 
    uint16_t tail; 
    uint16_t size; 
    bool full; 
    bool empty; 
} 

/* Implementation uses all non-volatile types. */ 
QUE_Handle QUE_init(void * data, uint_least8_t size, uint16_t capacity) { 
    /* ... */ 
    QUE_Handle q = (QUE_Handle)malloc(sizeof(struct QUE_Obj)); 
    /* ... */ 
    return q; 
} 

/* ... */ 

在queue.h:

typedef QUE_Obj * QUE_Handle; 
QUE_Handle QUE_init(void * data, uint_least8_t size, uint16_t capacity) 

main.c中:

/* Data buffer and queue handle declared to be for volatile data. */ 
static volatile uint16_t buffer[BUFFER_LENGTH] = {0}; 
volatile QUE_Handle que = QUE_init((void *)buffer); /* Buffer passed without volatile. */ 

我的问题然后,在最后一行在C中,当我将缓冲区投入到void *时,这是否会消除波动的任何有用性?

我应该代替定义QUE_Obj的成员始终动荡,调整中实现中使用挥发无论队列的使用的类型?

问另一种方式,push()pop()功能是从中断服务例程中调用的,但是它们的实现并不知道波动性,它们是否会被优化掉?

+4

*如果尝试 通过使用带非易失性限定类型的左值 来引用通过volatile限定类型定义的对象,则该行为是未定义的。*您应该声明指针具有挥发性。只是在说。 – this

+0

@这很好,谢谢你的标准报价! – Toby

回答

5

您不应该通过非易失性指针访问易失性数据。考虑下面这个简单的例子:

volatile int volatileVar; 
int* nonVolatilePtr = &volatileVar; 

每当你的代码访问volatileVar通过nonVolatilePtr编译知道你正在访问的数据是不稳定的,可能去优化访问它(这显然是一个意外的行为)。我看到非易失性指针用于非易失性数据的用处很少。

如果你希望你的队列通过中断服务例程(或类似)我会使整个数据结构来波动可能访问。

+0

感谢您的例子(假设你的意思是“通过'nonVolatilePtr'”) – Toby

+0

@Toby良好的渔获:)编辑 – mziccard

+0

为了澄清,你的意思我至少需要'挥发性INT * PTR = volatileVar;'或'挥发性INT * volatile ptr =&volatileInt;'? – Toby