Ресурсы для управления памятью во встроенном приложении
Как мне управлять памятью в моем критически важном встроенном приложении?
Я нашел несколько статей с 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() может быть выполнена с ошибкой.
Это действительно, действительно, действительно зависит от поставленной задачи и того, на какой доске будет работать.