簡體   English   中英

嵌入式應用程序中的內存管理資源

[英]Resources for memory management in embedded application

我應該如何管理關鍵任務嵌入式應用程序中的內存?

我發現了谷歌的一些文章,但無法確定一個非常有用的實用指南。

DO-178b禁止動態內存分配,但是如何管理內存呢? 提前預先分配所有內容並發送指向需要分配的每個函數的指針? 在堆棧上分配它? 使用全局靜態分配器(但它與動態分配非常相似)?

例如,答案可以是常規答案,對資源的引用或對良好的開源嵌入式系統的引用。

澄清:這里的問題不在於內存管理是否適用於嵌入式系統。 但是什么是嵌入式系統的優秀設計,以最大限度地提高可靠性。

我不明白為什么靜態預分配緩沖池,並動態地獲取和刪除它,與動態分配內存不同。

作為處理過嵌入式系統的人,雖然到目前為止還沒有這么嚴格(但我已經讀過DO-178B):

  • 如果你看一下u-boot bootloader,就可以通過全局放置的結構完成很多工作。 根據您的具體應用,您可以擺脫全局結構和堆棧。 當然,那里有重新進入和相關的問題並不真正適用於引導加載程序,但可能適合您。
  • 預分配,預分配,預分配。 如果您可以在設計時綁定數組/列表結構/ etc的大小,則將其聲明為全局(或靜態全局 - 外觀Ma,封裝)。
  • 堆棧非常有用,在需要的地方使用它 - 但要小心,因為在沒有剩余堆棧空間之前可以很容易地分配它。 我曾經發現自己調試的一些代碼會在多個函數中為字符串管理分配1k緩沖區...偶爾,緩沖區的使用會觸及另一個程序的堆棧空間,因為默認堆棧大小為4k。
  • 緩沖池情況可能取決於它的實現方式。 如果您知道需要傳遞編譯時已知大小的固定大小的緩沖區,那么處理緩沖池可能比完整的動態分配器更容易證明正確性。 您只需要驗證緩沖區不會丟失,並驗證您的處理不會失敗。 這里似乎有一些很好的提示: http//www.cotsjournalonline.com/articles/view/101217

但實際上,我認為您的答案可能會在加入http://www.do178site.com/時找到

我曾在DO-178B環境(飛機系統)工作過。 我所理解的是,不允許動態分配的主要原因主要是認證。 認證通過測試(單一,覆蓋,集成......)完成。 通過這些測試,您必須證明您的程序行為是100%可預測的,幾乎到了從一個執行到下一個執行的過程的內存占用量相同的程度。 由於動態分配是在堆上完成的(並且可能失敗),因此您無法輕易證明(我認為如果您掌握從硬件到編寫的任何代碼的所有工具,但是......)應該是可能的。 靜態分配沒有這個問題。 這也是為什么此類環境中此時不使用C ++的原因。 (大約15年前,這可能已經改變了......)

實際上,你必須編寫很多結構池和分配函數,以保證你有一些確定性的東西。 你可以想象很多解決方案。 關鍵是你必須證明(通過TONS測試)高水平的確定性行為。 更容易證明你的手工制作開發工作確定性地證明linux + gcc在分配內存方面是確定性的。

只需2美分。 很久以前,事情可能已經發生了變化,但是關於像DO-178B這樣的認證,關鍵在於證明你的應用程序在任何情況下都可以隨時工作。

實時,長時間運行,關鍵任務系統不應動態分配和釋放堆中的內存。 如果您需要並且無法圍繞它進行設計,那么請編寫自己的分配和固定池管理方案。 是的,盡可能提前分配固定。 還有其他事情要求最終的麻煩。

免責聲明:我沒有專門使用DO-178b,但我已經為認證系統編寫了軟件。

在我作為開發人員的認證系統上,......

  1. 僅在初始化階段,動態內存分配是可接受的。
  2. 動態內存解除分配絕對不可接受。

這給我們留下了以下選擇......

  • 使用靜態分配的結構。
  • 創建一個結構池,然后從/向池中獲取/釋放它們。
  • 為了靈活性,我們可以在初始化階段動態分配池的大小或結構的數量。 但是,一旦超過初始階段,我們就會陷入困境。

我們公司發現,結構池然后從/返回池中獲取/釋放是最有用的。 我們能夠保持模型,並以最小的問題保持確定性。

希望有所幫助。

從堆棧中分配所有內容通常在嵌入式系統或其他地方進行,其中分配失敗的可能性是不可接受的。 我不知道DO-178b是什么,但是如果問題是你的平台上沒有malloc,你也可以自己實現它(實現你自己的堆),但這仍然可能導致你運行時分配失敗當然,沒有太空了。

沒有辦法百分百肯定。

您可以查看FreeRTOS的內存分配器示例。 那些使用靜態池,如果我沒有弄錯的話。

您可能會發現此問題也很有趣,在空間強化設置中通常禁止動態分配(實際上,核心內存在那里仍然有用)。

通常,當malloc()不可用時,我只使用堆棧。 正如Tronic所說,不使用malloc()背后的全部原因是它可能會失敗。 如果您使用的是全局靜態池,則可以想象您的內部malloc()實現可以進行故障驗證。

它真的,真的,真的,取決於手頭的任務以及董事會將要接觸到的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM