2017-03-18 75 views
0

这是我的头文件(Header.h)volatile变量或用C挥发性结构问题

#include <stdio.h> 
#include <string.h> 
void Process(void); 

和 “Header.C”

#include <stdio.h> 
#include <string.h> 
#include "Header.h" 

struct St{ 
    unsigned long int volatile Var1; 
    unsigned long int volatile Var2; 
    unsigned char volatile Flag; 
}; 

extern struct ST Variable; 

void Process(void){ 
Variable.Var1=Variable.Var2; 
} 

和主文件:

#include <stdio.h> 
#include <string.h> 
#include "Header.h" 

struct St{ 
    unsigned long int volatile Var1; 
    unsigned long int volatile Var2; 
    unsigned char volatile Flag; 
}; 

struct ST Variable; 

//Interrupt each 10us 

void TIM_IRQHandler(){ 

//Do something 

    if(something==True) 
    { 
    Variable.Flag=1; 
    Variable.Var2=AVariable; //AVariable is between 30-40 
    } 

} 

int main(){ 

    while(1) 
    { 
    //wait 10ms 
    if(Variable.Flag==1) 
     { 
     Process(); 
     Variable.Flag=0; 
     } 

    } 

} 

正如你可以看到一个中断每10us发生一次,如果它正确地执行了一些代码,它将改变Var2的数值在30-40之间,并设置一个Flag变量乐。在主代码中,如果标志已被设置,它应该是呼叫处理功能并且用Var2值更改Var1。 但有时我收到var1与其他奇怪的值,他们是不正确的。我测试了我的中断,我发现我从来没有填写我的Var2奇怪的值。

void TIM_IRQHandler(){ 

//Do something 


    if(something==True) 
    { 
    Variable.Flag=1; 
    Variable.Var2= < 30-40>; 
    } 
    if(Variable.Var2>40 || Variable.Var2<30){ 
     printf("ERROR"); 
    } 

} 

和所有中断功能工作正常,但在过程功能,它让我生气。

我会欣赏任何我没有注意到的技巧。

+0

这是什么意思? 'Variable.Var2 = < 30-40>;'它是如何编译的? – Arash

+0

这不是我的确切代码,但它意味着它的值可能在30到40之间 –

+0

@Ehsan Zakeri:当前一个结果仍在处理中时,您有可能发生第二次中断触发和'Var2'的潜在竞赛。如果读取不是原子的,比如在一个典型的8位MCU上,那么你可能会得到一些来自前一个值的字节,一些来自新的。最简单的解决方法是在Process之前重置'Variable.Flag'并测试,看看它是否在之后再次被提升,在这种情况下,你可以旋转并重试。相反,该标志应该是'sig_atomic_t'类型,在实践中这不太可能是个问题。还有其他需要注意的问题。 – doynax

回答

1

在任何类型的typedef中使用关键字“volatile”时都不要期待什么。您正在声明类型“struct St”,包括关键字。您的描述意味着您期望在变量“变量”上存在易变的行为,该变量是在没有关键字的情况下定义和声明的。 根据我的经验,有时只有关键字(取决于平台和编译器)在类型内有效果。如果在变量的定义和声明中使用它,似乎可靠地起作用。

尝试改变

struct ST Variable; 

volatile struct ST Variable; 

extern struct ST Variable; 

extern volatile struct ST Variable; 

而且,在“St”!=“ST”周围是否存在一个错字,并且在其他地方声明了“struct ST”类型?
另外,作为一个便笺,您可能想要将您的类型声明移动到标题中。

我目前无法访问C环境,所以请原谅我不测试我的答案。

+0

这个答案指的是挥发性的有效性,考虑到它是发布的问题的相关部分;因为标题。正如其他人所评论的那样,彻底防止赛车条件对于实现这一目标也非常重要。 – Yunnosch

+0

你碰巧记得这个失败的编译器吗?我从来没有遇到与嵌入到typedef中的特定于成员的'volatile'(或'const')限定符或限定符有关的问题,尽管我可能会错误地说明它们的用法,没有人质疑那里有编译器破解。 – doynax

+0

抱歉无法为我的发言提供一些基础。我曾与几个编译器合作,其中大多数交叉编译器用于嵌入式设备。关于嵌入式设备上的“const”: – Yunnosch