• 招生咨詢熱線:4008-569-579 
  • 手機版
    用手機掃描二維碼直達商品手機版
招生咨詢熱線
4008-569-579
機構主頁 > 培訓資料 > 嵌入式開發(fā):嵌入式軟件錯誤的5大原因
機構主頁 > 培訓資料>嵌入式開發(fā):嵌入式軟件錯誤的5大原因

嵌入式開發(fā):嵌入式軟件錯誤的5大原因

來源:廣州達內教育        時間:2023-05-30        熱度:40℃        返回列表

  在嵌入式軟件中發(fā)現(xiàn)并消除潛在的bug是一件困難的事情。要從觀察到的崩潰、掛起或其他計劃外運行時行為追溯到根本原因,通常需要付出巨大的努力和昂貴的工具。嵌入式開發(fā)工程師們常常放棄尋找罕見異常的原因——因為這些異常無法在實驗室中輕易重現(xiàn)——而將其視為“用戶錯誤”或“小故障”,然而,機器中的這些潛在危機仍然一直存在。


  因此,這里有一個關于難以重現(xiàn)的固件錯誤最常見的根本原因的指南。


  1. 堆碎片


  嵌入式軟件開發(fā)人員并未廣泛使用動態(tài)內存分配——這是有充分理由的,其中之一是堆碎片的問題。


  通過 C 的 malloc() 標準庫例程或 C++ 的 new 關鍵字創(chuàng)建的所有數(shù)據結構都存在于堆中。堆是 RAM

中預先確定的最大大小的特定區(qū)域。最初,堆中的每個分配都會將剩余的“可用”空間減少相同的字節(jié)數(shù)。


  不再需要的數(shù)據結構的存儲可以通過調用 free() 或使用 delete

關鍵字返回到堆中。從理論上講,這使得該存儲空間可在后續(xù)分配期間重復使用。但是分配和刪除的順序通常至少是偽隨機的——導致堆變成一堆更小的碎片。


  2. 堆棧溢出


  每個程序員都知道堆棧溢出是一件非常糟糕的事情?。 但是,每個堆棧溢出的影響各不相同。

損害的性質和不當行為的時間完全取決于破壞了哪些數(shù)據或指令以及如何使用它們。重要的是,堆棧溢出與其對系統(tǒng)的負面影響之間的時間長度取決于使用破壞位之前的時間長度。


  不幸的是,在嵌入式開發(fā)中,堆棧溢出對嵌入式系統(tǒng)的影響遠遠超過對臺式計算機的影響。這有幾個原因,包括:


  嵌入式系統(tǒng)通常只能依靠少量的 RAM;


  通常沒有可依賴的虛擬內存(因為沒有磁盤);


  基于 RTOS

任務的固件設計利用多個堆棧(每個任務一個),每個堆棧的大小都必須足夠大,以確保不會出現(xiàn)唯一的最壞情況堆棧深度;


  中斷處理程序可能會嘗試使用這些相同的堆棧。




  3. 缺少“volatile”關鍵字


  未能使用 C

的“volatile”關鍵字標記某些類型的變量,可能會導致系統(tǒng)出現(xiàn)許多癥狀,這些癥狀只有在編譯器的優(yōu)化器設置為低級別或禁用時才能正常工作。 volatile

限定符在變量聲明期間使用,其目的是防止優(yōu)化該變量的讀取和寫入。


  請注意,除了確保對給定變量進行所有讀取和寫入之外,使用 volatile 還會通過添加額外的“序列點”來限制編譯器。對多個

volatile 的訪問必須按照它們在代碼中的寫入順序執(zhí)行。


  4. 比賽條件


  競爭條件是指兩個或多個執(zhí)行線程(可以是 RTOS 任務或 main() 加

ISR)的組合結果根據每個指令交錯的精確順序而變化的任何情況。


  例如,假設嵌入式開發(fā)人員有兩個執(zhí)行線程,其中一個定期遞增全局變量 (g_counter += 1;),另一個偶爾重置它

(g_counter =

0;)。如果增量不能始終以原子方式執(zhí)行(即,在單個指令周期中),則此處存在競爭條件。計數(shù)器變量的兩次更新之間的沖突可能永遠不會或很少發(fā)生。但是當它這樣做時,計數(shù)器實際上不會在內存中重置。這種影響可能會對系統(tǒng)產生嚴重后果,盡管可能要等到實際碰撞后很長時間才會發(fā)生。


  最佳實踐:可以通過圍繞必須以適當?shù)膿屨枷拗菩袨閷υ訄?zhí)行的代碼的“關鍵部分”來防止競爭條件。為了防止涉及 ISR

的競爭條件,必須在其他代碼的關鍵部分期間至少禁用一個中斷信號。在 RTOS

任務之間競爭的情況下,最佳實踐是創(chuàng)建特定于該共享對象的互斥鎖,每個任務必須在進入臨界區(qū)之前獲取該互斥鎖。請注意,依靠特定 CPU

的功能來確保原子性并不是一個好主意,因為這只會防止競爭條件,直到更改編譯器或 CPU。


  5. 不可重入函數(shù)


  從技術上講,不可重入函數(shù)的問題是競爭條件問題的一個特例。

出于這個原因,由不可重入函數(shù)引起的運行時錯誤是相似的,也不會以可重現(xiàn)的方式發(fā)生——這使得它們同樣難以調試。

不幸的是,與其他類型的競爭條件相比,不可重入函數(shù)在代碼審查中也更難發(fā)現(xiàn)。


  使函數(shù)可重入的關鍵是暫停對外圍寄存器、全局變量(包括靜態(tài)局部變量)、持久堆對象和共享內存區(qū)域的所有訪問的搶占。嵌入式開發(fā)人員可以通過禁用一個或多個中斷或通過獲取和釋放互斥鎖來完成,共享數(shù)據類型的細節(jié)通常決定了最佳解決方案。

電話咨詢

電話咨詢

咨詢電話:
4008-569-579
回到頂部

回到頂部