Распределение памяти под uCOS-III

Я разрабатываю C-библиотеку для использования в uCOS-III. Процессор представляет собой ARM Cortex M4 SAM4C. В библиотеке я хочу использовать сторонний продукт X, конкретное имя которого здесь не имеет значения. Исходный код для X полностью доступен и компилируется без проблем.

Внутри X выполняется много операций выделения памяти с помощью calloc() и free(). Проблема в том, что простое использование malloc нецелесообразно для встраиваемых систем из-за фрагментации памяти. Документация для uCOS-III явно не рекомендует использовать malloc — вместо этого следует использовать OSMemCreate/OSMemGet/OSMemPut для выделения и освобождения фрагментов памяти из статически выделенного блока памяти.

Вопрос 1:

Каков общий совет, чтобы обойти «стандартную реализацию» malloc? Я бы предпочел своего рода malloc, где у меня есть доступ к фиксированному пулу памяти (например, выделенному для специальной задачи)

Вопрос 2:

Как правильно использовать OSMemCreate()? Сначала я должен инициализировать раздел памяти с определенным размером блока. Объем запрашиваемой памяти составляет от 4 байт до примерно 800 байт. Я могу получить блоки по запросу, но с фиксированным размером. Если размер блока = 4, я не могу выделить 16 байт, так как блоки не являются смежными в памяти. Если размер блока = 800, а мне нужно всего 4 байта, большая часть блока остается неиспользованной, и у меня очень скоро закончатся блоки.

Поэтому я не знаю, как решить мою первоначальную проблему с помощью OSMemCreate...

Может ли кто-нибудь дать мне совет, как я могу действовать?

Большое спасибо, Майкл


person MichaelW    schedule 06.09.2016    source источник
comment
Фрагментация, пожалуй, наименьшая из проблем с malloc в системе реального времени. По умолчанию malloc не является ни детерминированным, ни потокобезопасным. Выделение занимает переменное время и может завершиться ошибкой, и если поток вытесняется на полпути через выделение или освобождение, а затем вытесняющий поток выполняет операцию выделения/освобождения, управление кучей будет повреждено таким образом, что может не вызвать заметного поведения до тех пор, пока некоторые последующие alloc/free. В вашей библиотеке C могут быть хуки для обеспечения потокобезопасности через мьютекс, но это может дополнительно повлиять на детерминированное поведение в реальном времени.   -  person Clifford    schedule 07.09.2016


Ответы (1)


1) Не связывайтесь со стандартной версией библиотеки malloc/free. Вместо этого создайте свою собственную реализацию malloc/free, которая служит оболочкой для OSMemGet/OSMemPut.

2) Вы можете создать более одного раздела памяти с помощью OSMemCreate. Создавайте малые, средние и большие разделы, содержащие размеры блоков, настроенные для вашего приложения, чтобы уменьшить количество отходов.

Если вы хотите, чтобы malloc получал блок соответствующего размера из различных разделов памяти, вам придется изобрести какую-то магию, чтобы free вернула блок в соответствующий раздел памяти. (Возможно, malloc выделяет дополнительное слово, сохраняет указатель на раздел памяти в первом слове, а затем возвращает адрес после слова, где хранится указатель. Тогда free знает, что нужно получить указатель раздела памяти из предыдущего слова.)

Альтернативой использованию malloc/free является переписывание этого кода для использования статически выделенных переменных или прямой вызов OSMemGet/OSMemPut.

person kkrambo    schedule 06.09.2016
comment
Этот совет был великолепен ;-) Я реализовал его так, как вы предложили, и он работает очень хорошо. - person MichaelW; 07.09.2016