背景:
最近在學習stm32l152晶元,看到對應的hal庫中經常見到volatile關鍵字,對該關鍵字不是很明白,所以總結一下該關鍵字的使用。
學習內容記錄:
volatile單詞的意思:易變的。在學習volatile之前,先簡單理解一下編譯器的優化。如下例:
uint8_t i;
i=0;
i=1;
i=2;
這段程式中,編譯器可能會認為只有i=2;這句才有意思,把i儲存在某個暫存器中,當要使用i時從這個暫存器讀取資料,若i由於中斷或多執行緒而使i的變數位址的資料改變,那麼讀取i的值可能就不一致,進而導致程式執行錯誤。
volatile關鍵字就可以避免上述錯誤的出現,提高**的魯棒性,也體現了程式設計師必備的一種基本功。
volatile提醒編譯器它後面所定義的變數隨時都有可能改變,因此編譯後的程式每次需要儲存或讀取這個變數的時候,都會直接從變數位址中讀取資料。如果沒有volatile關鍵字,則編譯器可能優化讀取和儲存,可能暫時使用暫存器中的值,如果這個變數由別的程式更新了的話,將出現不一致的現象。
下面以stm32的hal庫中的例子繼續講解volatile關鍵字,如定時器結構體中暫存器的定義
繼續go to definition of '_io'如下;
可以看到_io定義語句中後面的關鍵字,指明在暫存器的對映中,暫存器中的資料也是易改變的。
下面以乙個例項說明volatile關鍵字的使用。
uint8_t flag;
int main()
while(1)
void tim_irqhandler(void)
上述函式的功能是當發生定時器的中斷時,把flag置1,while(1)迴圈中檢測到flag 的值改變為1,便會去執行自己的程式do();
需要注意的是,沒有volatile也可能能正常執行,但是可能修改了編譯器的優化級別之後就又不能正常執行了。因此經常會出現debug版本正常,但是release版本卻不能正常的問題。所以為了安全起見,只要是等待別的程式修改某個變數的話,就加上volatile關鍵字。修改後的程式如下:
volatile uint8_t flag;
int main()
while(1)
void tim_irqhandler(void)
總結:
volatile 關鍵字提醒編譯器定義的變數是易變的,編譯後的程式每次需要儲存或讀取該變數時,會直接從變數位址讀取資料。在中斷或多執行緒中使用volatile關鍵字可以避免不同優化等級時程式出錯,提高程式的魯棒性。
c語言中volatile關鍵字
volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改 比如 作業系統 硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的 就不再進行優化,從而可以提供對特殊位址的穩定訪問。使用該關鍵字的例子如下 int volatile nvint 當要求使...
C語言中volatile關鍵字
一 前言 程式的優化 1 硬體級別上的優化 a.由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。b.在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。2 軟...
C語言中volatile關鍵字
1.編譯器優化介紹 由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。另外在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。以上是硬體級別的優化。再看軟體一級...