您的位置:首頁>正文

嵌入式開發必知的七個技巧

↑ 點擊上方“電子工程專輯”輕鬆關注

成為一個正式的嵌入式開發工程師。 它是一個艱辛的過程, 需要開發人員維護和管理系統的每個比特和位元組。 從規範完善的開發週期到嚴格執行和系統檢查, 開發高可靠性嵌入式系統的技術有許多種。 今天給大家介紹7個易操作且可以長久使用的技巧, 它們對於確保系統更加可靠地運行並捕獲異常行為大有幫助。

技巧1——用已知值填充ROM

軟體發展人員往往都是非常樂觀的一群人, 只要讓他們的代碼忠實地長時間地運行就可以了, 僅此而已。 微控制器跳出應用程式空間並在非預想的代碼空間中執行這種情況似乎是相當少有的。

然而, 這種情況發生的機會並不比緩存溢出或錯誤指標失去引用少。 它確實會發生!發生這種情況後的系統行為將是不確定的, 因為預設情況下記憶體空間都是0xFF, 或者由於記憶體區通常沒有寫過, 其中的值可能只有上帝才知道。

不過有相當完備的linker或IDE技巧可以用來幫助識別這樣的事件並從中恢復系統。 技巧就是使用FILL命令對未用ROM填充已知的位元模式。 要填充未使用的記憶體, 有很多不同的可能組合可以使用, 但如果是想建立更加可靠的系統, 最明顯的選擇是在這些位置放置ISR fault handler。 如果系統出了某些差錯, 處理器開始執行程式空間以外的代碼,

就會觸發ISR, 並在決定校正行動之前提供儲存處理器、寄存器和系統狀態的機會。

技巧2——檢查應用程式的CRC

對嵌入式工程師來說一個很大的好處是, 我們的IDE和工具鏈可以自動產生應用程式或記憶體空間校驗和(Checksum), 從而根據這個校驗和驗證應用程式是否完好。 有趣的是, 在許多這些案例中, 只有在將程式碼載入到設備時, 才會用到校驗和。

然而, 如果CRC或校驗和保持在記憶體中, 那麼驗證應用程式在啟動時(或甚至對長時間運行的系統定期驗證)是否仍然完好是確保意外之事不會發生的極好途徑。 現在一個程式設計過的應用程式發生改變的概率是很小的, 但考慮每年交付的數十億個微控制器以及可能惡劣的工作環境,

應用程式崩潰的機會並不是零。 更有可能的是, 系統中的一個缺陷可能導致某一磁區發生快閃記憶體寫入或快閃記憶體擦除, 從而破壞應用程式的完整性。

技巧3——在啟動時執行RAM檢查

為了建立一個更加可靠和扎實的系統, 確保系統硬體正常工作非常重要。 畢竟硬體會發生故障。 (幸運的是軟體永遠不會發生故障, 軟體只會做代碼要它做的事, 不管是正確的還是錯誤的)。 在啟動時驗證RAM的內部或外部沒有問題, 是確保硬體可以如預期般運作的一個好方法。

有許多不同的方法可用於執行RAM檢查, 但常用的方法是寫入一個已知的模式, 然後等上一小段時間再回讀。 結果應該是所讀就是所寫。 真相是, 在大多數情況下 RAM檢查是通過的,

這也是我們想要的結果。 但也有極小的可能性檢查不通過, 這時就為系統標示出硬體問題提供了極好的機會。

技巧4——使用堆疊監視器

對許多的嵌入式開發者而言, 堆疊似乎是一股相當神秘的力量。 當奇怪的事情開始發生, 工程師終於被難倒了, 他們開始思考, 也許堆疊中發生了什麼事。 結果是盲目地調整堆疊的大小和位置等等。 但該錯誤往往是與堆疊無關的, 但怎能如此確定?畢竟, 有多少工程師真的實際執行過最壞情況下的堆疊大小分析?

堆疊大小是在編譯時就靜態配置好的, 但堆疊是以動態的方式使用的。 隨著代碼的執行, 應用程式需要的變數、返回的位址和其它資訊被不斷存儲在堆疊中。

這種機制導致堆疊在其分配的記憶體中不斷增長。 然而, 這種增長有時會超出編譯時確定的容量極限, 導致堆疊破壞相鄰記憶體區域的資料。

絕對確保堆疊正常工作的一種方法是實現堆疊監視器, 將它作為系統“保健”代碼的一部分(有多少工程師會這樣做?)。 堆疊監視器會在堆疊和“其它”記憶體區域之間創建一個緩衝區域, 並填充已知的位元模式。 然後監視器會不斷的監視圖案是否有任何變化。 如果該位元模式發生了改變, 那就意味著堆疊增長得太大了, 即將要把系統推向黑暗地獄!此時監視器可以記錄事件的發生、系統狀態以及任何其它有用的資料, 供日後用於問題的診斷。

大多數即時操作系統(RTOS)或實現了記憶體保護單元(MPU)的微控制器系統中都提供有堆疊監視器。 可怕的是,這些功能預設都是關閉狀態,或者經常被開發人員有意關閉。在網路上快速搜尋一下可以發現,很多人建議關閉即時操作系統中的堆疊監視器以節省56位元組的快閃記憶體空間等等,這可是得不償失的做法!

技巧5 - 使用MPU

在過去,是很難在一個小而廉價的微控制器中找到記憶體保護單元(MPU)的,但這種情況已經開始改變。現在從高端到低端的微控制器都已經有MPU,而這些 MPU為嵌入式軟體發展人員提供了一個可以大幅提高其固件(firmware)魯棒性(robustness)的機會。

MPU 已逐漸與作業系統耦合,以便建立記憶體空間,其中的處理都分開,或任務可執行其代碼,而不用擔心被stomped on。倘若真有事情發生,不受控制的處理會被取消,也會執行其他的保護措施。請留意帶有這種元件的微控制器,如果有,請多加利用它的這種特性。

技巧6 - 建立一個強大的看門狗系統

你經常會發現的一種總是最受喜愛的看門狗(watchdog)實現是,在看門狗被啟用之處(這是一個很好的開始),但也是可以用週期性計時器將該看門狗清零之處;計時器的啟用是完全與程式中出現的任何情況隔離的。使用看門狗的目的是協助確保如果出現錯誤,看門狗不會被清零,即當工作暫停,系統會被迫去執行硬體重設定(hardware reset),以便恢復。使用與系統活動獨立的計時器可以讓看門狗保持清零,即使系統已失效。

對應用任務如何整合到看門狗系統中,嵌入式開發人員需要仔細考慮和設計。例如,有種技術可能可以讓每個在一定時期內運行的任務標示它們可以成功地完成其任 務。在此事件中,看門狗不被清零,強制被復位。還有一些比較先進的技術,像是使用外部看門狗處理器,它可用來監視主處理器如何表現,反之亦然。對一個可靠的系統而言,建立一個強大的看門狗系統是很重要的。

技巧7 - 避免動態記憶體分配

不習慣在資源有限環境下工作的工程師,可能會試圖使用其程式設計語言的特性,這種語言讓他們可以使用動態記憶體分配。畢竟,這是一種常在計算器系統中使用的技術,在計算器系統中,只有在有必要時,記憶體才會被分配。例如,以C開發時,工程師可能傾向于使用malloc來分配在堆(heap)上的空間。有一個操 作會執行,一旦完成,可以使用free將被分配的記憶體返回,以便堆的使用。

在資源受限的系統,這可 能是一場災難!使用動態記憶體分配的其中一個問題是,錯誤或不當的技術可能會導致記憶體洩漏或記憶體碎片。如果出現這些問題時,大多數的嵌入式系統並沒有 資源或知識來監視堆或妥善地處理它。而當它們發生時,如果應用程式提出對空間的要求,但卻沒有所請求的空間可以使用,會發生什麼事呢?

使用動態記憶體分配所產生的問題是很複雜的,要妥善處理這些問題,可以說是一個噩夢!一種替代的方法是,直接以靜態的方式,簡化記憶體的分配。例如,只要在 程式中簡單地建立一個大小為256位元組長的緩衝區,而不是經由malloc請求這樣大小的記憶體緩衝區。此一分配的記憶體可在整個應用程式的生命週期期 間保持,且不會有堆或記憶體碎片問題方面的顧慮。

結論

以上嵌入式開發的教程可以讓開發技術的人員獲取更好嵌入式系統的辦法。所有這些技術都是讓設計者可以開發出可靠性更高嵌入式系統的秘訣。

看完本文有收穫?請分享給更多人

關注「電子工程專輯」,做優秀工程師!

回復關鍵字有乾貨:電路設計丨電容丨三極管丨PCB丨接地‧‧‧‧‧‧

長按二維碼識別關注

閱讀原文可一鍵關注+歷史資訊

可怕的是,這些功能預設都是關閉狀態,或者經常被開發人員有意關閉。在網路上快速搜尋一下可以發現,很多人建議關閉即時操作系統中的堆疊監視器以節省56位元組的快閃記憶體空間等等,這可是得不償失的做法!

技巧5 - 使用MPU

在過去,是很難在一個小而廉價的微控制器中找到記憶體保護單元(MPU)的,但這種情況已經開始改變。現在從高端到低端的微控制器都已經有MPU,而這些 MPU為嵌入式軟體發展人員提供了一個可以大幅提高其固件(firmware)魯棒性(robustness)的機會。

MPU 已逐漸與作業系統耦合,以便建立記憶體空間,其中的處理都分開,或任務可執行其代碼,而不用擔心被stomped on。倘若真有事情發生,不受控制的處理會被取消,也會執行其他的保護措施。請留意帶有這種元件的微控制器,如果有,請多加利用它的這種特性。

技巧6 - 建立一個強大的看門狗系統

你經常會發現的一種總是最受喜愛的看門狗(watchdog)實現是,在看門狗被啟用之處(這是一個很好的開始),但也是可以用週期性計時器將該看門狗清零之處;計時器的啟用是完全與程式中出現的任何情況隔離的。使用看門狗的目的是協助確保如果出現錯誤,看門狗不會被清零,即當工作暫停,系統會被迫去執行硬體重設定(hardware reset),以便恢復。使用與系統活動獨立的計時器可以讓看門狗保持清零,即使系統已失效。

對應用任務如何整合到看門狗系統中,嵌入式開發人員需要仔細考慮和設計。例如,有種技術可能可以讓每個在一定時期內運行的任務標示它們可以成功地完成其任 務。在此事件中,看門狗不被清零,強制被復位。還有一些比較先進的技術,像是使用外部看門狗處理器,它可用來監視主處理器如何表現,反之亦然。對一個可靠的系統而言,建立一個強大的看門狗系統是很重要的。

技巧7 - 避免動態記憶體分配

不習慣在資源有限環境下工作的工程師,可能會試圖使用其程式設計語言的特性,這種語言讓他們可以使用動態記憶體分配。畢竟,這是一種常在計算器系統中使用的技術,在計算器系統中,只有在有必要時,記憶體才會被分配。例如,以C開發時,工程師可能傾向于使用malloc來分配在堆(heap)上的空間。有一個操 作會執行,一旦完成,可以使用free將被分配的記憶體返回,以便堆的使用。

在資源受限的系統,這可 能是一場災難!使用動態記憶體分配的其中一個問題是,錯誤或不當的技術可能會導致記憶體洩漏或記憶體碎片。如果出現這些問題時,大多數的嵌入式系統並沒有 資源或知識來監視堆或妥善地處理它。而當它們發生時,如果應用程式提出對空間的要求,但卻沒有所請求的空間可以使用,會發生什麼事呢?

使用動態記憶體分配所產生的問題是很複雜的,要妥善處理這些問題,可以說是一個噩夢!一種替代的方法是,直接以靜態的方式,簡化記憶體的分配。例如,只要在 程式中簡單地建立一個大小為256位元組長的緩衝區,而不是經由malloc請求這樣大小的記憶體緩衝區。此一分配的記憶體可在整個應用程式的生命週期期 間保持,且不會有堆或記憶體碎片問題方面的顧慮。

結論

以上嵌入式開發的教程可以讓開發技術的人員獲取更好嵌入式系統的辦法。所有這些技術都是讓設計者可以開發出可靠性更高嵌入式系統的秘訣。

看完本文有收穫?請分享給更多人

關注「電子工程專輯」,做優秀工程師!

回復關鍵字有乾貨:電路設計丨電容丨三極管丨PCB丨接地‧‧‧‧‧‧

長按二維碼識別關注

閱讀原文可一鍵關注+歷史資訊

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示