IAR для ARM под управлением Micrium OS-III - Понимание использования памяти
- Как определить размер стека, используемого задачами, сгенерированным файлом MAP?
- Как определить размеры стека и кучи в оперативной памяти ARM
- Как определить, требуется ли больший размер стека для задач?
1 ответ
Если вы используете последнюю версию IAR EWARM, есть встроенный инструмент, который вам очень пригодится при решении этих вопросов.
- Как определить размер стека, используемого задачами, сгенерированным файлом MAP?
Для первого вопроса вам нужно будет найти в файле карты имя стека каждой задачи. В этом случае файл карты не так уж полезен, так как вам, вероятно, лучше будет поискать в своем проекте CPU_STK
введите, так как это даст вам результаты со всеми правильно определенными стеками. Если вы посмотрите в файле карты, вы можете увидеть такую строку:
MainStack 0x20000000 0x1000 Data Lc main.o [1]
Это означает, что MainStack
(предположительно стек для MainTask
) размером 0x1000 или 4096 байт. Первый столбец - имя символа, второй - местоположение в адресном пространстве, третий - размер, четвертый - тип (Данные, Код), пятый - область (Lc = локальный, Gb = Глобальный), и последний столбец - объектный модуль, в котором он находится.
Если вместо этого вы ищете в проекте экземпляры CPU_STK
Вы найдете следующее:
static CPU_STK MainStack[4096];
Это дает вам ту же информацию, что MainStack
имеет размер 4096, но при поиске CPU_STK он также даст вам результаты для других задач, так что вы можете увидеть в своих результатах следующее:
static CPU_STK MainStack[4096];
static CPU_STK AuxStack[512];
Итак, теперь вы можете видеть, что есть также AuxStack
(предположительно для AuxTask
), и это 512 байт. Это потребует поиска в файле карты определенных имен стеков, чтобы получить результаты, поэтому мне было бы проще.
- Как определить размеры стека и кучи в оперативной памяти ARM?
Для этого вам нужно будет закопать либо файл конфигурации компоновщика, либо раздел компоновщика в настройках. Более простой способ - через варианты. Перейдите к параметрам проекта, а затем к элементу Linker слева. На вкладке конфигурации выберите Edit..., а затем перейдите на вкладку Stack/Heap. Это даст вам легкий доступ к размерам, которые IAR будет использовать для выделения областей памяти HEAP и CSTACK в компоновщике.
Кроме того, вы можете покопаться в .icf
файл, и вы можете найти набор строк, например, так:
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x400;
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
Это также может выглядеть совершенно по-другому! Трудно дать обобщенный ответ на этот вопрос, поэтому лучше всего искать варианты. В приведенном выше коде вы можете увидеть CSTACK
а также HEAP
их размеры определены символами, определенными ранее в файле. Вы можете следовать этим определениям, чтобы получить размер. Ваш файл компоновщика может сильно отличаться от этого, хотя, как я уже сказал, очень сложно дать общий ответ.
- Как определить, требуется ли больший размер стека для задач?
В новых версиях IAR есть отличная утилита, которая может определить глубину стека, необходимую для любой функции. В настройках проекта в разделе "Линкер" на вкладке "Дополнительно" можно установить флажок "Включить анализ использования стека". Когда вы включите это, ваш файл карты будет содержать корневые функции и их максимальную цепочку вызовов. Например, мой MainTask
выглядит так:
Uncalled function
"MainTask" in main.o [1]: 0x0000ac41
Maximum call chain *?* 396 bytes
Итак, это говорит мне о том, что MainTask - это не вызванная функция (которая вызывается не напрямую, а по указателю на функцию, которую IAR не может разрешить автоматически), и ей требуется стек в 396 байт. Ниже он покажет вам цепочку вызовов, которая добавляет до 396 байтов.
С этим инструментом следует отметить, что если вы используете указатели на функции и косвенные вызовы, IAR не может автоматически определить, к чему они ведут. Есть набор pragma
директивы, которые можно использовать, чтобы указать, какие возможные функции вызываются в косвенной точке вызова, и вам нужно будет их вставить, чтобы получить 100% точную глубину стека.
Альтернативой является запуск программы на вашем оборудовании, но пусть ОС отслеживает переполнение стека. У Micrium есть страница об обнаружении переполнения стека здесь: Обнаружение переполнения стека задач. Кроме того, вот документация по функции для получения информации об использовании стека задачи: OSTaskStkChk ()