代码之家  ›  专栏  ›  技术社区  ›  Elazar Leibovich

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

  •  7
  • Elazar Leibovich  · 技术社区  · 16 年前

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

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

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

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

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

    我不明白为什么静态地预分配缓冲池,动态地获取和丢弃它,与动态地分配内存是不同的。

    7 回复  |  直到 10 年前
        1
  •  4
  •   Arthur Shipkowski    16 年前

    作为一个处理过嵌入式系统的人,虽然到目前为止还没有这么严格(不过,我读过do-178b):

    • 如果您看看u-boot引导加载程序,很多工作都是通过全局放置的结构完成的。根据您的具体应用程序,您可能能够避开全局结构和堆栈。当然,有一些重入和相关的问题并不真正适用于引导加载程序,但可能适合您。
    • 预分配,预分配,预分配。如果可以在设计时绑定数组/列表结构/etc的大小,请将其声明为全局(或静态全局——look ma,封装)。
    • 堆栈是非常有用的,在需要的地方使用它——但是要小心,因为在没有堆栈空间之前,很容易一直从堆栈中分配。我曾经调试过的一些代码会在多个函数中为字符串管理分配1K缓冲区……偶尔,缓冲区的使用会影响到另一个程序的堆栈空间,因为默认的堆栈大小是4K。
    • 缓冲池的情况可能取决于它是如何实现的。如果您知道您需要传递在编译时已知大小的固定大小缓冲区,那么处理缓冲池可能比完整的动态分配器更容易演示正确性。您只需要验证缓冲区不会丢失,并且验证您的处理不会失败。这里似乎有一些好的建议: http://www.cotsjournalonline.com/articles/view/101217

    不过,我想你的答案可能是 http://www.do178site.com/

        2
  •  2
  •   neuro    16 年前

    我在do-178b环境(飞机系统)工作过。据我所知,不允许动态分配的主要原因是认证。认证通过测试(统一、覆盖、集成等)完成。通过这些测试,您必须证明您的程序行为是100%可预测的,几乎到了这样的程度:从一次执行到下一次执行,您的进程的内存占用是相同的。由于动态分配是在堆上完成的(而且可能会失败),您无法轻松证明(我想如果您掌握了从硬件到编写的任何代码段的所有工具,应该是可能的,但是…)。静态分配没有这个问题。这也是为什么C++在这个环境中不被使用的原因。(那是大约15年前,可能已经改变了……)

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

    就我的2美分。很久以前,事情可能已经改变了,但是关于do-178b这样的认证,关键是要证明你的应用程序在任何情况下都可以在任何时候工作。

        3
  •  1
  •   kenny    16 年前

    实时、长时间运行、任务关键型系统不应动态分配和释放堆内存。如果你 需要 并且不能围绕它来设计然后编写自己的分配和固定池管理方案。是的,只要有可能就提前安排好。任何其他的事情都会带来最终的麻烦。

        4
  •  1
  •   Sparky    16 年前

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

    在我作为开发人员的认证系统上,…

    1. 动态内存分配是 仅在 初始化阶段。
    2. 动态内存取消分配是不可接受的。

    这给我们留下了以下选择…

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

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

    希望能有所帮助。

        5
  •  0
  •   Tronic    16 年前

    从堆栈中分配所有内容通常是在嵌入式系统或其他地方完成的,在这些地方分配失败的可能性是不可接受的。我不知道do-178b是什么,但是如果问题是malloc在您的平台上不可用,那么您也可以自己实现它(实现自己的堆),但是当您耗尽空间时,这仍然可能导致分配失败。

        6
  •  0
  •   Roman Dmitrienko    16 年前

    不可能百分之百确定。

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

        7
  •  0
  •   Community Mohan Dere    9 年前

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

    通常,当malloc()不可用时,我只使用堆栈。AS Tronic 也就是说,不使用malloc()的全部原因是它可能会失败。如果您使用的是全局静态池,那么可以想象您的内部malloc()实现可以成为防失败的。

    这真的,真的,真的取决于手头的任务和董事会将面临的挑战。