volatile的本意為"易變的"的意思
由於存取暫存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的最佳化。
例如:
static int i=0;
int main(void)
{
...
while (1)
{
if (i) dosomething();
}
}
/* Interrupt service routine. */
void ISR_2(void)
{
i=1;
}
此程式的本意是希望ISR_2中斷產生時,在main當中調用dosomething函式是,
但由於編譯器判斷在main函式裡面沒有修改過i,
因此可能只執行一次對從i到每暫存器的Read操作,
然後每次if判斷都只使用這個暫存器裡面的“i副本”,
導致dosomething永遠不會被引用。如果將變數加上volatile來修飾,
則編譯器保證對此變數的Read/Write操作都不會被最佳化(肯定會被執行)。
此例子中i也應該如此說明。
一般來說,volatile用在以下幾個地方:
1、中斷伺服程式中修改的供其它程式檢測的變量需要加volatile。
2、多任務環境下各任務間共享的標誌應該加volatile。
3、記憶位址對應的硬體暫存器通常也要加volatile,因為每次對它的Read/Write都有可能有不同的意義。
另外,以上幾種情況經常還要同時考慮數據的完整性
(相互關聯的幾個標誌Read一半被打斷了而重新Write),
第1項目中可以通過關中斷方式來實現,
第2項目中可以禁止任務調度,
第3項目中則只能依靠硬體的良好設計。