嵌入式应用程序中的内存管理资源

时间:2010-03-18 12:54:29

标签: c memory-management embedded malloc do178-b

如何管理关键任务嵌入式应用程序中的内存?

我在google上发现了一些文章,但无法找到真正有用的实用指南。

DO-178b禁止动态内存分配,但是如何管理内存呢?提前预先分配所有内容并发送指向需要分配的每个函数的指针?在堆栈上分配它?使用全局静态分配器(但它与动态分配非常相似)?

例如,答案可以是常规答案,对资源的引用或对良好的开源嵌入式系统的引用。

澄清:这里的问题不在于内存管理是否适用于嵌入式系统。但是什么是嵌入式系统的优秀设计,以最大限度地提高可靠性。

我不明白为什么静态预分配缓冲池,动态获取和删除它,与动态分配内存不同。

7 个答案:

答案 0 :(得分:4)

作为处理过嵌入式系统的人,虽然到目前为止还不是那么严格(不过我读过DO-178B):

  • 如果你看一下u-boot bootloader,那么全局放置的结构会做很多事情。根据您的具体应用,您可以摆脱全局结构和堆栈。当然,那里有重新进入和相关的问题并不真正适用于引导加载程序,但可能适用于你。
  • 预分配,预分配,预分配。如果你可以在设计时绑定数组/列表结构/ etc的大小,则将其声明为全局(或静态全局 - 看看Ma,封装)。
  • 堆栈非常有用,在需要的地方使用它 - 但要小心,因为在没有剩余堆栈空间之前,可以很容易地分配它。我曾经发现自己调试的一些代码会为多个函数中的字符串管理分配1k缓冲区...偶尔,缓冲区的使用会占用另一个程序的堆栈空间,因为默认堆栈大小为4k。
  • 缓冲池案例可能取决于其实现方式。如果您知道需要传递编译时已知大小的固定大小的缓冲区,那么处理缓冲池可能比完整的动态分配器更容易证明正确性。您只需要验证缓冲区不会丢失,并验证您的处理不会失败。这里似乎有一些很好的提示:http://www.cotsjournalonline.com/articles/view/101217

但是,我认为您的答案可能会在加入http://www.do178site.com/

时找到

答案 1 :(得分:2)

我曾在DO-178B环境(飞机系统)工作过。我所理解的是,不允许动态分配的主要原因主要是认证。认证通过测试(单一,覆盖,集成......)完成。通过这些测试,您必须证明您的程序行为是100%可预测的,几乎到了从一个执行到下一个执行的过程的内存占用量相同的程度。由于动态分配是在堆上完成的(并且可能失败),因此您无法轻易证明(我认为如果您掌握从硬件到编写的任何代码的所有工具,但是......)应该是可能的。静态分配没有这个问题。这也是为什么此类环境中此时不使用C ++的原因。 (大约15年前,这可能已经改变了......)

实际上,你必须编写很多结构池和分配函数来保证你有一些确定性的东西。你可以想象很多解决方案。关键是你必须证明(通过TONS测试)高水平的确定性行为。更容易证明你的手工制作开发工作确定性地证明linux + gcc在分配内存方面是确定性的。

只需2美分。很久以前,事情可能已经发生了变化,但是关于像DO-178B这样的认证,关键在于证明你的应用程序在任何情况下都可以随时工作。

答案 2 :(得分:1)

实时,长时间运行,关键任务系统不应动态分配和释放堆中的内存。如果您需要并且无法围绕它进行设计,那么请编写自己的已分配和固定池管理方案。是的,尽可能提前分配固定。还有其他事情要求最终的麻烦。

答案 3 :(得分:1)

免责声明:我没有专门使用DO-178b,但我已经为认证系统编写了软件。

在我曾经是开发人员的认证系统上......

  1. 动态内存分配是 只有在接受期间才能接受 初始化阶段。
  2. 动态内存取消分配绝对不可接受。
  3. 这给我们留下了以下选项......

    • 使用静态分配的结构。
    • 创建一个结构池,然后从/向池中获取/释放它们。
    • 为了灵活性,我们可以在初始化阶段动态分配池的大小或结构的数量。然而,一旦超过初始阶段,我们就会陷入困境。

    我们公司发现结构池然后从/返回池中获取/释放是最有用的。我们能够保持模型,并以最小的问题保持确定性。

    希望有所帮助。

答案 4 :(得分:0)

从堆栈中分配所有内容通常在嵌入式系统或其他地方进行,否则分配失败的可能性是不可接受的。我不知道DO-178b是什么,但如果问题是你的平台上没有malloc,你也可以自己实现它(实现你自己的堆),但这仍然可能导致你运行时分配失败当然,没有太空了。

答案 5 :(得分:0)

没有办法百分百肯定。

您可以查看FreeRTOS的内存分配器示例。那些使用静态池,如果我没有弄错的话。

答案 6 :(得分:0)

您可能会发现this question也很有趣,在空间强化设置中经常禁止动态分配(实际上,核心内存在那里仍然有用)。

通常,当malloc()不可用时,我只使用堆栈。正如Tronic所说,不使用malloc()背后的全部原因是它可能会失败。如果您使用的是全局静态池,则可以想象您的内部malloc()实现可以进行故障验证。

这真的,真的,真的取决于手头的任务以及董事会将要接触到的内容。