嵌入式C中volatile和const的用法

2021-08-03 15:39:15 字數 1434 閱讀 6800

volatile本意為「易變的」。

在嵌入式環境中用volatile關鍵字宣告的變數,在每次對其值進行引用的時候都會從原始位址取值,而不會將值儲存在棧或其他位置。

由於該值「易變」的特性所以,針對其的任何賦值或者獲取值操作都會被執行(而不會被優化)。由於這個特性,所以該關鍵字在嵌入式編譯環境中經常用來消除compiler的優化。

uint8_t *addr =...; //裝置位址 

*addr = 1; //第乙個指令

*addr = 2; //第二個指令

以上程式compiler可能做優化而成:

int *addr = ...; 

*addr = 2;

結果第乙個指令丟失。如果用volatile, compiler就不允許做任何的優化,從而保證程式的原意,mcu庫函式中對於io暫存器的宣告都會使用volatile。

volatile uint8_t *addr = ...; 

*addr = 1;

*addr = 2;

2.用volatile定義的變數會在程式外被改變,每次都必須從記憶體中讀取,而不能重複使用放在暫存器或棧中的備份。

例如:

volatile uint8_t flag;

flag=0;

while(!flag)

dosomethingelse();

如果沒有volatile修飾flag則 dosomethingelse()可能由於編譯器優化不會被執行(即使flag的值在其他中斷中被更改)。若如上使用了volatile,則會每次都會從原始位址取值,這樣當原始位址的值更改後則while能中止並繼續執行下方**。

3.很容易得知多工環境下各任務間共享的標誌也應該加volatile。

4.儲存器對映的硬體暫存器通常也要加voliate,因為每次對它的讀寫都可能有不同意義。

例如:假設要對乙個裝置進行初始化,此裝置的某乙個暫存器為0******x。

int *uartsendregist= (unsigned  int *)0*********x;//定義乙個串列埠資料暫存器位址;

int init(void)

}

1.本意為變數唯讀

2.大部分微控制器的compiler會把中const修飾的全域性變數存放在mcu的rom中.把一些很大的不變資料申明為const。

3.使編譯器很自然地保護那些不希望被改變的引數,防止其被無意的**修改。

順便說乙個問題,乙個引數既可以是const還可以是volatile嗎?

這是可以的,因為const的意思是唯讀,而不是不變。最簡單的例子比如唯讀的狀態暫存器。

嵌入式中 volatile 用法

volatile 影響編譯器編譯的結果,指出,volatile 變數是隨時可能發生變化的,與volatile變數有關的運算,不要進行編譯優化,以免出錯,vc 在產生release版可執行碼時會進行編譯優化,加volatile關鍵字的變數有關的運算,將不進行編譯優化。例如 volatile int i...

嵌入式C之volatile的解釋

當程式執行在某乙個函式內讀取變數時,為了提高訪問速度,編譯器通常會先把變數讀取到乙個暫存器裡,暫存器操作是最快的。然後以後需要再用到這個變數的時候,就直接從暫存器裡拿,而不用再通過記憶體位址去訪問記憶體再取一次了。注意,只有當該變數在本函式內被改變時,暫存器裡的儲存才會更新,才會和這次記憶體的改變保...

嵌入式C學習

靜態變數與靜態函式 extern變數 關鍵字const和巨集定義define 程式中所有數在計算機記憶體中都是以二進位制的形式儲存的。位運算就是直接對整數在記憶體中的二進位制位進行操作。常見的位運算有 and運算 or運算 xor運算 not運算 shl運算 和shr運算 and運算通常用於二進位制...