本期話題:
群友在群里咨詢的一個問題:Freertos 里高優先級的任務中改變了全局變量值,低優先級的任務中循環等待值的改變;為何高優先級任務里的值改變后,低優先級循環沒有結束并向下執行呢?
高優先級任務中的代碼,修改全局變量:
if(1000 <= Complete)
{
????update_flag = 1;
????printf("update_flag = [%d]\n”, update_flag);
}
vTaskDelay(10);while(!update_flag); // 判斷
......你知道為什么低優先級任務中 while() 沒有退出嗎?
聊一聊:
如果你能想到關鍵詞 volatile,那么恭喜你,你已經真正理解了這個關鍵詞。
告訴這位小伙伴在全局變量定義的時候,加上 volatile。問題得到解決。好了,萬事大吉。
顯然,為了證實我們的猜想,我們進行逐步分析。
首先,查看這個項目的工程配置,是否開啟開了編譯器優化,如下圖所示:

這個項目開啟了編譯一級優化。這樣就解釋通了,編譯器開啟了優化,并且變量定義沒有添加關鍵詞 volatile 。這兩點組合起來導致問題發生。
編譯器開啟優化后,編譯器認為在循環的過程中,沒人會修改 update_flag。既然不修改 update_flag,并且 update_flag 一開始的值為 0,那么 update_flag 就是一個不會改變的值,當然就是死循環!
顯然,編譯器并不知道高優先級任務會修改 update_flag 的值。
所以,在這種情況下,就需要程序員顯式的告訴編譯器,update_flag 是一個會發生改變的值,所以不要嘗試做這樣的優化。這就是 volatile 關鍵字的作用。
注意:volatile 只作用于編譯階段,對運行階段沒有任何影響。
這位小伙伴說,如果在低優先級代碼中添加一些代碼,執行結果就可以正常(變量定義沒有添加 volatile ):
while(!update_flag)
{
????printf("update_flag = [%d]\n”, update_flag);
????vTaskDelay(10);
}
END
→點關注,不迷路←