Как определить подходящий размер стека и кучи для ARM Cortex, используя C ++ - PullRequest
12 голосов
/ 12 марта 2011

Файл запуска процессора Cortex M3 позволяет указать объем оперативной памяти, выделенной для стека и кучи. Для базы кода C ++ есть общее правило или, возможно, какой-то более явный способ определения значений для стека и размеров кучи? Например, вы посчитаете количество и размер уникальных объектов или, возможно, будете использовать размер скомпилированного кода?

Ответы [ 4 ]

16 голосов
/ 12 марта 2011

Файл запуска процессора Cortex M3 позволяет указать объем оперативной памяти, выделенной для стека и кучи.

Это не функция Cortex-M3, а скореестартовый код, предоставляемый вашим набором инструментов разработки.Это способ запуска по умолчанию файлов запуска Keil ARM-MDK для M3.Это немного необычно;чаще вы указали бы размер стека, и любая оставшаяся память после стека и статическое выделение памяти компоновщиком становится кучей;это, возможно, лучше, так как у вас нет пула неиспользуемой памяти.Вы можете изменить это и использовать альтернативную схему, но вам нужно знать, что вы делаете.

Если вы используете Keil ARM-MDK, опции компоновщика --info =stack и --callgraph добавляют информацию в файл карты, которая помогает анализировать требования стека.Эти и другие методы описаны здесь .

Если вы используете RTOS или многозадачное ядро, у каждой задачи будет свой стек.Операционная система может предоставлять инструменты для анализа стека, в средстве просмотра ядра RTX Keil отображается текущее использование стека, но не пиковое использование стека (поэтому оно в основном бесполезно и работает корректно только для задач с длиной стека по умолчанию).

Если вам нужноРеализуйте инструменты проверки стека самостоятельно, нормальный метод - заполнить стек известным значением, и, начиная с старшего адреса, проверять значение, пока не найдете первое значение, которое не является байтом заполнения, это даст высокую оценку Ликли.стека.Для этого можно реализовать код или вручную заполнить память из отладчика, а затем отслеживать использование стека в окне памяти отладчика.

Требование кучи будет зависеть от поведения вашего кода во время выполнения;вам придется проанализировать это самостоятельно, однако в ARM / Keil Realview обработчик исключений MemManage будет вызываться, когда C ++ new генерирует исключение;Я не уверен, что malloc() делает это или просто возвращает NULL.Вы можете поместить точку останова в обработчик исключений или изменить обработчик так, чтобы он выдавал сообщение об ошибке, чтобы обнаружить исчерпание кучи во время тестирования.Существует также функция __ heapstats () , которую можно использовать для вывода информации о куче.У него несколько громоздкий интерфейс, я обернул его так:

void heapinfo()
{
typedef int (*__heapprt)(void *, char const *, ...);
    __heapstats( (__heapprt)std::fprintf, stdout ) ;
}
3 голосов
/ 12 марта 2011

Размер скомпилированного кода не поможет, так как код не работает ни в стеке, ни в куче.Устройства Cortex-M3 обычно реализуются на микроконтроллерах со встроенной Flash и относительно небольшим объемом оперативной памяти.В этой конфигурации код обычно запускается из Flash.

Куча используется для динамического выделения памяти.Подсчет количества уникальных объектов даст вам приблизительную оценку, но вы также должны учитывать любые другие элементы, которые используют динамическое распределение памяти (используя ключевое слово new в C ++).Как правило, во встроенных системах динамическое выделение памяти исключается по той причине, что размером кучи сложно управлять.

Стек будет использоваться для передачи переменных, локальных переменных и сохранения контекста во время процедур обработки исключений.Как правило, трудно получить хорошее представление об использовании стека, если ваш код не выделяет большой блок локальной памяти или большие объекты.Один из методов, который может помочь, - это выделить всю доступную оперативную память для стека.Заполните стек известным шаблоном (0x00 или 0xff - не лучший выбор, так как эти значения встречаются часто), некоторое время запустите систему, а затем проверьте стек, чтобы узнать, сколько его было использовано.По общему признанию, это не очень точный, ни научный подход, но все же полезный во многих случаях.

1 голос
/ 03 июля 2013

Сокращение до тех пор, пока оно не выйдет из строя, это быстрый специальный метод. Вы также можете заполнить стек известным значением, скажем, 0xCCCC, а затем отслеживать максимальное использование стека путем сканирования на 0xCCCC. Это несовершенно, но гораздо лучше, чем искать сбой.

Смысл в том, что уменьшение размера стека не гарантирует, что переполнение стека вызовет нечто "видимое".

1 голос
/ 07 февраля 2012

В последней версии компилятора IAR есть функция, которая определяет, какой размер стека вам нужен, на основе статического анализа вашего кода (при условии, что у вас нет рекурсии).

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

...