Ресурсы для управления памятью во встроенном приложении

Как мне управлять памятью в моем критически важном встроенном приложении?

Я нашел несколько статей с Google, но не смог определить действительно полезное практическое руководство.

DO-178b запрещает распределение динамической памяти, но как вы будете управлять памятью? Предварительно выделите все заранее и отправьте указатель на каждую функцию, которая требует выделения? Выделить его в стеке? Использовать глобальный статический распределитель (но тогда он очень похож на динамическое распределение)?

Ответы могут иметь форму регулярного ответа, ссылки на ресурс или ссылки на хорошую встроенную систему с открытым исходным кодом, например.

пояснение: Проблема здесь заключается не в том, доступно ли управление памятью для встроенной системы. Но что такое хороший дизайн для встроенной системы, чтобы обеспечить максимальную надежность.

Я не понимаю, почему статически предопределять буферный пул и динамически получать и удалять его, отличается от динамического выделения памяти.

Ответ 1

Как кто-то, кто занимался встроенными системами, хотя и до сих пор не до такой степени (я прочитал DO-178B, хотя):

  • Если вы посмотрите на загрузочный загрузчик u-boot, многое будет сделано с размещенной в глобальном масштабе структурой. В зависимости от вашего конкретного приложения вы можете уйти с глобальной структурой и стеком. Конечно, есть проблемы с повторным подключением и связанные с ними проблемы, которые на самом деле не применяются к загрузчику, но могут для вас.
  • Предопределить, предварительно распределить, предварительно распределить. Если вы можете во время компоновки связать размер структуры массива/списка/и т.д., Объявите его глобальным (или статическим глобальным взглядом Ma, инкапсуляцией).
  • Стек очень полезен, используйте его там, где это необходимо, но будьте осторожны, поскольку его можно легко отложить, пока у вас не осталось свободного пространства. Некоторый код, который я когда-то обнаружил, отлаживал бы выделение буферов 1k для управления строкой в ​​нескольких функциях... Иногда использование буферов ударяло бы в другое пространство стека программ, поскольку размер стека по умолчанию был 4k.
  • Случай с пулом буферов может зависеть от того, как он реализован. Если вы знаете, что вам нужно передавать буферы фиксированного размера с размером, известным во время компиляции, то, имея дело с пулом буферов, вероятно, легче продемонстрировать правильность, чем полный динамический распределитель. Вам просто нужно проверить, что буферы не могут быть потеряны, и проверка вашей обработки не будет терпеть неудачу. Здесь, возможно, есть несколько полезных советов: http://www.cotsjournalonline.com/articles/view/101217

Действительно, я думаю, что ваши ответы могут быть найдены при присоединении http://www.do178site.com/

Ответ 2

Я работал в среде DO-178B (системы для самолетов). То, что я понял, заключается в том, что основной причиной отказа от динамического распределения является в основном сертификация. Сертификация проводится через тесты (унитарные, покрытие, интеграция,...). С этими тестами вы должны доказать, что поведение вашей программы на 100% предсказуемо, почти до такой степени, что объем памяти вашего процесса одинаковый от одного исполнения к другому. Поскольку динамическое распределение выполняется в куче (и может терпеть неудачу), вы не можете легко доказать это (я предполагаю, что это должно быть возможно, если вы освоите все инструменты с аппаратного обеспечения на любой написанный код, но...). У вас нет этой проблемы со статическим распределением. Именно поэтому С++ не использовался в настоящее время в таких средах. (это было около 15 лет назад, это могло измениться...)

Практически вам нужно написать много структурных пулов и функций распределения, которые гарантируют, что у вас есть что-то детерминированное. Вы можете представить множество решений. Ключ в том, что вам нужно доказать (с ТОНН испытаний) высокий уровень детерминированного поведения. Легче доказать, что ваша ручная работа развивается детерминистически, чтобы доказать, что linux + gcc детерминирован при распределении памяти.

Только мои 2 цента. Это было давно, все могло измениться, но относительно сертификации, такой как DO-178B, нужно доказать, что ваше приложение будет работать одинаково в любое время в любом контексте.

Ответ 3

В режиме реального времени, долго работающие критически важные системы не должны динамически выделять и освобождать память из кучи. Если вам нужно и не можете создать вокруг него, чтобы затем написать свою собственную схему распределения выделенных и фиксированных пулов. Да, назначается заранее, когда это возможно. Все остальное просит о возможных проблемах.

Ответ 4

Отказ от ответственности: я не работал специально с DO-178b, но я написал программное обеспечение для сертифицированных систем.

В сертифицированных системах, для которых я был разработчиком,...

  • Динамическое распределение памяти было приемлемо ТОЛЬКО во время фаза инициализации.
  • Отмена распределения динамической памяти НИКОГДА не была приемлемой.

Это оставило нам следующие варианты...

  • Использование статически распределенных структур.
  • Создайте пул структур, а затем получите/отпустите их/назад в пул.
  • Для гибкости мы можем динамически распределять размер пулов или количество структур на этапе инициализации. Однако, когда-то прошедший этап инициализации, мы застряли с тем, что у нас было.

Наша компания обнаружила, что пулы структур, а затем получать/освобождать из/обратно в бассейн, были наиболее полезными. Мы смогли сохранить модель и сохранить детерминированные вещи с минимальными проблемами.

Надеюсь, что это поможет.

Ответ 5

Выделение всего из стека обычно выполняется во встроенных системах или в других местах, где вероятность сбоя распределения неприемлема. Я не знаю, что такое DO-178b, но если проблема в том, что malloc недоступен на вашей платформе, вы также можете реализовать его самостоятельно (реализуя свою собственную кучу), но это все равно может привести к сбою в распределении при запуске вне пространства, конечно.

Ответ 6

Нет возможности быть на 100% уверенным.

Вы можете посмотреть примеры свободных распределителей памяти FreeRTOS. Они используют статический пул, если я не ошибаюсь.

Ответ 7

Возможно, вы найдете этот вопрос, динамическое распределение часто запрещено в настройках с упрощенным пространством (на самом деле, основная память по-прежнему полезна там).

Обычно, когда malloc() недоступен, я просто использую стек. Как сказал Tronic, вся причина, по которой не используется malloc(), состоит в том, что она может выйти из строя. Если вы используете глобальный статический пул, можно предположить, что ваша внутренняя реализация malloc() может быть выполнена с ошибкой.

Это действительно, действительно, действительно зависит от поставленной задачи и того, на какой доске будет работать.