2015-08-07 53 views
7

我最近一直在自己學習嵌入式系統編程。在聲明變量時,我觀察到關鍵字volatile修飾符的使用率相當高?關於嵌入式系統,「易失性」關鍵字有什麼意義?

在嵌入式系統編程中聲明變量時,volatile的意義是什麼?

基本上應該使用關鍵詞。我沒有讀過關於編譯器優化和使用關鍵字的內容。還有一些與內存映射寄存器有關。

例如,我讀了這個StackOverflow post,但我不明白它是如何在嵌入式環境中應用的。更具體地說,我不明白什麼時候應該使用關鍵詞。我沒有讀過關於編譯器優化和使用關鍵字的內容。還有一些與內存映射寄存器有關,但我不明白何時使用它。

+0

可能重複的[爲什麼在C中需要volatile?](http://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c) – Olaf

回答

6

在嵌入式系統領域,關鍵字volatile的一個關鍵方面是它表示一個隨時可能變化的變量(例如外部/硬件數據輸入 - 例如ADC),因此編譯器一定不能優化使用。

但是,具體來說,當與控制寄存器一起使用時,它表示讀取訪問實際上可能會更改數據!

根據經驗,一般情況下,我會建議使用volatile預選賽的所有如下:

  • 所有硬件寄存器的訪問(讀取和寫入)
  • 所有的變量都在訪問多線程(尤其是中斷處理程序)

注:訪問volatile是不是原子,所以它是你必須知道你的硬件和你的代碼結構。

9

讓我們來看一個例子。當你在C頭文件的PIC微控制器,你會看到許多元素的聲明volatile

extern volatile unsigned char   PORTB    @ 0x006; 

視爲您已閱讀,在volatile關鍵字關閉編譯器優化。假設你寫一個程序,執行以下操作:

PORTB = 0x00;   // set all of port B low 
while (PORTB == 0x00); // wait for any pin to get high 
// do something else 

當編譯器優化的代碼,它會識別第二線作爲一個無限循環:條件爲真和它的體內永遠不會假。因此,在之後的所有內容無需編譯,因爲它永遠不會運行。因此,編譯器可能決定在生成的彙編代碼中不包含該部分代碼。

但是,這個PORTB實際上鍊接到一個物理端口。它是一個硬件端口,其值可能會被外部電路改變。這意味着儘管循環似乎是無限的,但並不一定如此。編譯器不可能知道這一點。

這就是volatile進來。當PORTB聲明volatile,編譯器不會做基於對PORTB推理任何優化。它會假設它的價值可能隨時被外部因素所改變。

2

易失性關鍵字主要用於告訴編譯器該變量的值可能隨時改變。它還告訴編譯器不要對變量應用優化。我對這方面的專家並不太多,但以下是我過去提及的很好的參考資料。

揮發性是當它被聲明被施加到的變量的限定符。它告訴編譯器,變量的值可能隨時發生變化 - 編譯器在附近找不到任何代碼。這個影響非常嚴重。但是,在我們檢查它們之前,讓我們來看看語法。

參考:

+1

儘管這個鏈接理論上可以回答這個問題, [這將是最好的](http://meta.stackexchange.com/q/8259)在這裏包括答案的基本部分,並提供鏈接供參考。 – 2015-08-07 21:17:49

1

讓我把它放在其他角度來看,這是完全相反常量關鍵字。 當編譯器遇到const限定符的任何變量它檢查是否有任何函數或語句被修改後,它一旦初始化。因此標誌錯誤。

易失性正好相反,這個變量可以被任何函數改變。因此編譯器不會應用優化。

由於使用中斷,一些編程邏輯結構似乎是多餘的,您可以在嵌入式系統編程中看到這一點。

+3

Thist是不準確的。它可以通過您正在編寫的程序的外部因素進行更改*。可以被任何函數改變的變量被稱爲全局變量範圍變量,這與變量是否被聲明爲'volatile'正交。 – 2015-08-08 08:05:22