當前位置: 華文星空 > 知識

C語言開發微控制器為什麽大多數都采用全域變量的形式?

2020-05-23知識

作為一個和MCU,SOC芯片相伴多年的老程式猿,也來分享一下答主個人對全域變量這個問題的看法。 總的來說,對於大多數程式設計師來說全域變量可謂是又愛又恨 不用吧 ,很多場合下使用全域變量的確能夠節省很多編碼力氣,畢竟可以減少函數間的參數及數據傳遞; 用吧 ,很多時候對於多工或者說多執行緒場景,必須考慮互斥問題。對於Ram資源寸土寸金的MCU來說,更是需要小心謹慎。比如定義太大的全域變量,可能有時候就是放不到Ram資源中。

網圖,侵刪

嵌入式開發過程中,也曾經遇到過兩個與全域變量有過交集的故事,現在回頭想想也是很有思考的價值和意義。寫在這裏和大家一起分享分享。

第一個故事:老程式碼中過多的全域變量,導致維護起來非常麻煩 。答主剛入職的時候,從事的是嵌入式軟件平台的程式碼維護工作,可以說 前人留下的很多程式碼絕對配得上「屎山」的名聲 。其中一條就是,各種全域變量滿天飛。先不說各種spinlock,rwlock的保護解保護,單說用SI列舉出來的索引點,看著滿屏的extern真的讓人頭大。每次但凡要修改一點程式碼,就要全專案到處尋找這個全域變量還漏下了哪裏沒修改到。好在後期專案組開展了程式碼最佳化工作,答主直接憋著一口氣把這些陳年汙垢都給清除掉了。

第二個故事:超級大的全域變量,導致程式碼編譯失敗 。記得和別人一起做嵌入式消費產品的時候,有個軟件開發的同事,特別喜歡用全域變量定義各種功能。但是他真的忽略了stm32那瘦弱的小身板真的放不下他的 巨大無比的結構體陣列 。在stm32上,弄個結構體全域變量就夠夠了。還要弄個陣列,相當令人發指!編譯不透過,就修改堆和棧的大小,好不容易編譯透過了。結果一執行的時候,多工跑起來後各種不正常。耗費了好久發現,堆疊太小了,任務的變量發生了踩踏!!!

講了這麽多,並不是想妖魔化全域變量。 全域變量用好了,是個非常好的夥伴,但是用的不好,那絕對是史詩級別的災難 。在答主的個人編碼經驗裏, 對於全域變量主要遵循三點

  1. 能不用盡量不用,尤其對於多執行緒多工的場景下。使用任務通訊機制進行數據傳遞+局部變量儲存,基本可以滿足開發需要。
  2. 如果必須使用,那麽一定要限定起作用的模組。不要隨便一個新加入的模組,一個extern就將全域變量透漏出去,以後維護起來又要被人罵屎山。
  3. 如果一個模組中的全域變量超過了3個,那麽把他們放到一個結構體中。參照的時候一個extern足矣,不要一堆一堆的extern看著眼睛疼。

回到題主最後的問題: 很多時候使用全域變量並不一定是效能的問題,更多是的是程式猿想方便快捷的實作多模組下數據共享的問題 。至於提到的各種開發板或者demo程式使用全域變量過多的問題, 從答主的角度來看,這些程式碼僅僅作為示意使用,也就是說怎麽方便怎麽來,讓大家看懂怎麽用就行 。而在真正的嵌入式產品,至少在答主經歷和參與開發的各類嵌入式產品中,沒有像這麽大肆使用全域變量的情況。

以上,僅代表個人觀點,僅供題主參考。