Я работаю над проектом, который требует использования MCU для приема пакетов кадров с неизвестной длиной кадра при приеме, но каждый прием имеет октет, из которого вы можете вывести количество кадров, оставшихся для приема, и, следовательно, вычислить длину всего кадра .
В другом, чтобы избежать выделения фиксированной памяти для принимающего кадра, который может не использоваться (если длина принимаемого кадра меньше максимальной длины принимаемого кадра), я придерживаюсь мнения о динамическом выделении памяти для оставшегося кадра для быть полученным.
Например. Если мы предположим, что пакеты состоят из 20 октетов, а 3-й октет сообщает вам количество оставшихся октетов, которые нужно получить (это может быть максимум 2, 3 и даже 17 октетов). Вместо того, чтобы создавать регистр размером 17, который может не использоваться, как я могу динамически выделить эту память, особенно для встроенного приложения, так что, если 3-й октеты упиваются тем, что есть 6 октетов для приема, то я просто выделяю зарегистрируйте размер 6 для остальной части кадра, не используя «malloc».
Язык программирования — С.
Надеюсь, мой вопрос достаточно ясен. Пожалуйста, поделитесь своим мнением, так как мне нужно наилучшим образом подойти к этому.
Спасибо.
В этом случае я бы сказал, что лучший подход, вероятно, состоит в том, чтобы просто выделить максимальный размер памяти и повторно использовать ее для как можно большего количества других вещей.
В некоторых компиляторах есть возможность для переменных совместно использовать пространство памяти, если они не активны одновременно. Например, компилятор PIC18 C (теперь замененный на HI-Tech C) имеет атрибут overlay
, который можно использовать для этого с переменными.
Он также может обрабатывать массивы переменного размера, которые идеально подходят для того, что вы хотите сделать (меньше накладных расходов, чем malloc). Я бы проверил, может ли ваш компилятор это сделать.
Во многих системах с микроконтроллерами компиляторы и компоновщики размещают данные в нижней и/или верхней части ОЗУ; неиспользуемая оперативная память обычно находится в непрерывной области, и, как правило, можно убедить компоновщика сделать адреса начала и конца этой области доступными для программиста (например, можно попросить компоновщика поместить однобайтовую переменную в качестве самая последняя вещь перед свободной областью, а другая — самой первой после; адреса этих переменных очерчивают свободное пространство).
Хотя многие системы предлагают malloc()
функцию, во многих сценариях она сложнее, чем необходимо. Например, если нужно выделить объекты на основе информации, полученной во время выполнения, но объекты всегда будут освобождаться в порядке, обратном выделению, можно просто сохранить указатель на «следующее доступное пространство». Чтобы выделить объект, скопируйте этот указатель, добавьте к нему размер нового объекта и верните скопированный указатель. Чтобы освободить объект (и все, что находится после него), просто установите указатель «следующее доступное пространство» на начало этого объекта.
Некоторые сценарии немного сложнее, чем это было бы разрешено при таком подходе, но все же не нуждаются в полном подходе «malloc/free». Например, в некоторых сценариях может быть две группы объектов, которые между собой подчиняются правилу «последний пришел — первый ушел», но объекты в одной группе могут пережить объекты в другой. Чтобы справиться с этой ситуацией, используйте указатель «следующее доступное пространство», который начинается снизу свободного пространства, и указатель «предыдущее доступное пространство», который начинается вверху. Распределите вещи в первой группе, как и раньше. Для тех, кто во второй группе, вычтите размер нового объекта из указателя «предыдущее доступное пространство» и верните результат. Чтобы освободить объект второй группы (и все объекты второй группы, расположенные после него),
Обратите внимание, что malloc
иfree
спроектированы таким образом, что объекты в середине памяти могут быть освобождены, в то время как объекты до и после остаются действительными. Хотя иногда это может быть полезно, это также может привести к фрагментации памяти. Если чьи-либо объекты не соответствуют модели «последний пришел — первый ушел», может быть хорошей идеей сделать объекты перемещаемыми. Например, можно хранить очередь объектов переменного размера, которые последовательно сохраняются в памяти до тех пор, пока есть место. Когда память заполняется (или в какое-то удобное время до этого), можно было бы скопировать первый объект, который еще не был прочитан, в начало очереди, следующий объект, который не был прочитан сразу после него, и т. д. до тех пор, пока все объекты были скопированы, а свободное место, которое было в начале очереди, объединено в конец. Нужно быть осторожным при перемещении любых данных, чтобы убедиться, что указатели на эти данные обновляются соответствующим образом, но часто это не слишком сложно. Перемещение памяти может занять больше циклов ЦП, чем управление прерывистыми областями свободного пространства, но поведение подхода с перемещением памяти может быть более предсказуемым.
Бруно Феррейра
пометки
Пол А.
Пол А.
пометки
Бруно Феррейра
ДжастДжефф