Подтвердить что ты не робот

Как определить подходящие размеры стека и кучи для ARM Cortex, используя С++

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

4b9b3361

Ответ 1

Загрузочный файл процессора Cortex M3 позволяет указать количество ОЗУ, предназначенное для стека и куча.

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

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

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

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

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

void heapinfo()
{
typedef int (*__heapprt)(void *, char const *, ...);
    __heapstats( (__heapprt)std::fprintf, stdout ) ;
}

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

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