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

发布于 2024-08-25 19:12:18 字数 334 浏览 6 评论 0原文

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

我通过谷歌找到了一些文章,但无法找到真正有用的实用指南。

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

例如,答案可以采用常规答案、资源引用或优秀开源嵌入式系统引用的形式。

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

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

How should I manage memory in my mission critical embedded application?

I found some articles with google, but couldn't pinpoint a really useful practical guide.

The DO-178b forbids dynamic memory allocations, but how will you manage the memory then? Preallocate everything in advance and send a pointer to each function that needs allocation? Allocate it on the stack? Use a global static allocator (but then it's very similar to dynamic allocation)?

Answers can be of the form of regular answer, reference to a resource, or reference to good opensource embedded system for example.

clarification: The issue here is not whether or not memory management is availible for the embedded system. But what is a good design for an embedded system, to maximize reliability.

I don't understand why statically preallocating a buffer pool, and dynamically getting and dropping it, is different from dynamically allocating memory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

凉墨 2024-09-01 19:12:18

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

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

只是我的2分钱。这是很久以前的事了,事情可能已经发生了变化,但对于像 DO-178B 这样的认证,重点是证明您的应用程序在任何情况下都可以在任何时候正常工作。

I've worked in a DO-178B environment (systems for airplanes). What I have understood, is that the main reason for not allowing dynamic allocation is mainly certification. Certification is done through tests (unitary, coverage, integration, ...). With those tests you have to prove that you the behavior of your program is 100% predictable, nearly to the point that the memory footprint of your process is the same from one execution to the next. As dynamic allocation is done on the heap (and can fail) you can not easily prove that (I imagine it should be possible if you master all the tools from the hardware to any piece of code written, but ...). You have not this problem with static allocation. That also why C++ was not used at this time in such environments. (it was about 15 years ago, that might have changed ...)

Practically, you have to write a lot of struct pools and allocation functions that guarantee that you have something deterministic. You can imagine a lot of solutions. The key is that you have to prove (with TONS of tests) a high level of deterministic behavior. It's easier to prove that your hand crafted developpement work deterministically that to prove that linux + gcc is deterministic in allocating memory.

Just my 2 cents. It was a long time ago, things might have changed, but concerning certification like DO-178B, the point is to prove your app will work the same any time in any context.

等待圉鍢 2024-09-01 19:12:18

作为一个处理过嵌入式系统的人,尽管到目前为止还没有那么严格(不过我已经读过 DO-178B):

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

说实话,我认为您可以在加入 http://www.do178site 中找到答案。 com/

As someone who has dealt with embedded systems, though not to such rigor so far (I have read DO-178B, though):

  • If you look at the u-boot bootloader, a lot is done with a globally placed structure. Depending on your exact application, you may be able to get away with a global structure and stack. Of course, there are re-entrancy and related issues there that don't really apply to a bootloader but might for you.
  • Preallocate, preallocate, preallocate. If you can at design-time bind the size of an array/list structure/etc, declare it as a global (or static global -- look Ma, encapsulation).
  • The stack is very useful, use it where needed -- but be careful, as it can be easy to keep allocating off of it until you have no stack space left. Some code I once found myself debugging would allocate 1k buffers for string management in multiple functions...occasionally, the usage of the buffers would hit another program's stack space, as the default stack size was 4k.
  • The buffer pool case may depend on exactly how it's implemented. If you know you need to pass around fixed-size buffers of a size known at compile time, dealing with a buffer pool is likely more easy to demonstrate correctness than a complete dynamic allocator. You just need to verify buffers cannot be lost, and validate your handling won't fail. There seem to be some good tips here: http://www.cotsjournalonline.com/articles/view/101217

Really, though, I think your answers might be found in joining http://www.do178site.com/

芯好空 2024-09-01 19:12:18

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

在我担任开发人员的认证系统上,...

  1. 动态内存分配是
    仅在期间可接受
    初始化阶段。
  2. 动态内存解除分配是永远不可接受的。

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

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

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

希望有帮助。

Disclaimer: I've not worked specifically with DO-178b, but I have written software for certified systems.

On the certified systems for which I have been a developer, ...

  1. Dynamic memory allocation was
    acceptable ONLY during the
    initialization phase.
  2. Dynamic memory de-allocation was NEVER acceptable.

This left us with the following options ...

  • Use statically allocated structures.
  • Create a pool of structures and then get/release them from/back to the pool.
  • For flexibility, we could dynamically allocate the size of the pools or number of structures during the initialization phase. However, once past that init phase, we were stuck with what we had.

Our company found that pools of structures and then get/releasing from/back into the pool was most useful. We were able to keep to the model, and keep things deterministic with minimal problems.

Hope that helps.

零度° 2024-09-01 19:12:18

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

Real-time, long running, mission critical systems should not dynamically allocate and free memory from heap. If you need and cannot design around it to then write your own allocated and fixed pool management scheme. Yes, allocated fixed ahead of time whenever possible. Anything else is asking for eventual trouble.

残疾 2024-09-01 19:12:18

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

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

这真的、真的、真的取决于手头的任务以及董事会将面临的情况。

You might find this question interesting as well, dynamic allocation is often prohibited in space hardened settings (actually, core memory is still useful there).

Typically, when malloc() is not available, I just use the stack. As Tronic said, the whole reason behind not using malloc() is that it can fail. If you are using a global static pool, it is conceivable that your internal malloc() implementation could be made fail proof.

It really, really, really depends on the task at hand and what the board is going to be exposed to.

傾旎 2024-09-01 19:12:18

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

Allocating everything from stack is commonly done in embedded systems or elsewhere where the possibility of an allocation failing is unacceptable. I don't know what DO-178b is, but if the problem is that malloc is not available on your platform, you can also implement it yourself (implementing your own heap), but this still may lead to an allocation failing when you run out of space, of course.

此生挚爱伱 2024-09-01 19:12:18

没有办法 100% 确定。

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

There's no way to be 100% sure.

You may look at FreeRTOS' memory allocators examples. Those use static pool, if i'm not mistaken.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文