2017-03-18 28 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