Как стать автором
Обновить

Комментарии 14

А что у нас с фрагментацией памяти (malloc/free)? Или фиг с ней? Или аппликация будет работать от забора до обеда, если повезёт?
Простите, не очень понял вопрос? или вопросы?
Имеется в виду нужна ли для поддержки C++ реализация функций управления памятью (malloc/free). Конечно нужна, констуркторы то выделяют память, а деструкторы освобождают. Об этом упомянуто в статье. Но управление памятью, это отдельная огромная отдельная тема. В данной статье подразумевалось, что подобные вещи уже как то реализованы в составе ОС или стандартной библиотеки языка С.
Скорее вопрос был посвящен тому что если часто вызывать malloc free то в какой то момент память кучи будет фрагментирована и даже если у вас там есть свободный килобайт скажем, выделить 1КБ вы не сможете т.к. он раздроблен на микро-фрагменты в куче.
Проблема обычно решается просто — заказываешь при старте и в когда контроллер крутится уже заказом-освобождением памяти не пользуешься. Но на сколько это реально в рамках данной статьи утверждать не берусь
Не уверен, что в этом был вопрос. Но спасибо за разъяснение. Если используется C++ то вы гораздо меньше управляете выделением из кучи. То есть любой конструктор, в том числе и например копи конструктор, будет веделять память. Есть глобальные объкты, их память можно посчитать, но речь шла о том что нужно запускать любой софт. Соотвественно он будет опираться на кучу. Алгоритмы работы с кучей (стратегии выделения) могут быть разные. В Embox даже можно переключать эти стратегии, и да мы стараемся позволить выделять память из пулов где только можно, но все это выходит за рамки данной статьи.

Кстати если уж говорить о предсказуемом по времени выделении памяти, то это либо пулы либо выделение на стеке.
Да, пулы в этом плане решают многие проблемы.
Вы молодцы, двигаете хороший проект, особенно прекрасно, что могут учиться студенты.
Так как Вы явно знаете эту RTOS — могли бы Вы ответить на пару вопросов? Они не относятся к данной статье на прямую, но мы сейчас рассматриваем варианты нескольких RTOS и возможно ваши ответы могли бы склонить наш выбор в пользу Embox:
— какой уровень зрелости Embox? (скажем могли бы вы рекомендовать ее для мед устройств?)
— есть ли готовая и протестированная поддержка Risc-V
мы сейчас рассматриваем варианты нескольких RTOS и возможно ваши ответы могли бы склонить наш выбор в пользу Embox:

Были бы рады :)

— какой уровень зрелости Embox? (скажем могли бы вы рекомендовать ее для мед устройств?)

Уровень зрелости вполне приличный. Не хуже чем у большинства RTOS. Как минимум открытых которые подразумевают те или иные доработки под себя. Есть некоторые пробелы с текущей документацией, но мы работаем по данному направлению и уж точно компенсируем с полна быстрой и адекватной поддержкой на русском. Можно зайти на телеграм чат например (https://t.me/embox_chat)
Рекомендовать конечно могу. на Embox уже было сделано несколько медицинских устройст
— есть ли готовая и протестированная поддержка Risc-V

да, есть поддержка maix-bit и sifive
То есть любой конструктор, в том числе и например копи конструктор, будет веделять память.

Простите что?! Конструктор не вЫделяет память от слова совсем — он только инициализирует объект по переданному ему указателю. И например, если вы создаете объект на стеке (без new), то память под объект зарезервируется на стеке тоже.
И да "копи конструктор" тут тоже ничего не выделит (ибо оно уже выделено до него):


Test t1;
Test t2 = t1;

он будет лишь вызван и только.


Не путайте конструкторы и оператор new (new[] и иже с ними).


Соотвественно он будет опираться на кучу

Вовсе не обязан. Оператор new точно также можно переопределить — соотвеТственно он будет брать память хоть из стека (alloca и т.д.), хоть из пула (myownalloc), хоть из какого-либо ранее выделенного большего work-блока, который можно выделить одним куском для всей необходимой работы, например обработать request/response и освободить позже также одним куском (без какой-либо дефрагментации).

Спасибо. Извините за грубые упрощения. Конечно Вы правы, выделяется память оператором new (как я и написал в статье). Я имел в виду только, что программист часто не задумывается когда вызовется выделение памяти. На Си это как то более явно происходит. И динамическое выделение памяти отдельная гиганская тема, которую в данной статье я не рассматриваю.
Запуск сложных C++ приложений

подобные вещи уже как то реализованы в составе ОС или стандартной библиотеки

Вы предлагаете запускать сложную, стороннюю библиотеку (OpenCV например, с непредсказуемыми new/delete внутри нее), написанную на плюсах, на системе, где Вы не можете гарантировать отсутствие фрагментации памяти, по причине отсутствия полноценного MMU на контроллере. Вот и был вопрос — а сколько времени Ваше (мое ) приложение сможет проработать непрерывно. То-же и относительно STL.
Не знаю при чем тут MMU, или Вы имеете в виду что оно позвоняет больше непрерывного пространства получить?
Но ответ на вопрос сколько времени, столько же сколько на больших системах. Естсественно нужно указать достаточный объем кучи а для этого нужно иметь физическую память. Как оценить объем памяти для сложной стабильно работающей системы, мы рассказывали в статье «SIP-телефон c GUI на STM32F7»/, Но в остальном, все еще не вижу проблем с фрагментированностью. Кстати а о какой фрагментированности идет речь, внутри кучи или о страничной фрагментированности. Последней вообще нет на микроконтроллерах, нужно естественно выделить объем кучи в нашем случае можно извернуться и добавить несколько куч, но лучше одну непрерывную кучу.

А чем wasm3 и emscripten/wasienv не подошли?

Не очень понял о чем Вы говорите. Вы же приводите интерпретаторы или виртуальные машины. В статье описаны тонкости поддержки С++ рантайма нативного, в том числе на микроконтроллерах, то есть что называется bare-metal. Поэтому приведенные вами технологии как минимум уступают по скорости и требуют больше ресурсов. Если они вообще доступны на микроконтроллерах
Очень странная реализация operator new. Что такое alloc_failure_handler? Где вызов new_handler? Например, как в libstdc++.
Далее, что с bad_alloc? По Стандарту не бросающие исключений версии operator new должны сводиться к двум версиям, бросающим исключения — обычной и с выравнивание, таким образом их переопределение позволяет переопределить всё выделение памяти. Как с этим обстоит дело?
Вы правы и не правы одновременно. В статье рядом с реализацией написано, что это простая реализация без использования исключений.
таким образом их переопределение позволяет переопределить всё выделение памяти. Как с этим обстоит дело?

Приведена базовая реализация, она ничем не отличается от стандартной. Но ее естественно можно использовать только в случае отключения RTTI и Exceptions. Прочитайте пожалуйста статью.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.