IAR для ARM под управлением Micrium OS-III - Понимание использования памяти

  • Как определить размер стека, используемого задачами, сгенерированным файлом MAP?
  • Как определить размеры стека и кучи в оперативной памяти ARM
  • Как определить, требуется ли больший размер стека для задач?

1 ответ

Решение

Если вы используете последнюю версию IAR EWARM, есть встроенный инструмент, который вам очень пригодится при решении этих вопросов.

  1. Как определить размер стека, используемого задачами, сгенерированным файлом 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 байт. Это потребует поиска в файле карты определенных имен стеков, чтобы получить результаты, поэтому мне было бы проще.

  1. Как определить размеры стека и кучи в оперативной памяти 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 их размеры определены символами, определенными ранее в файле. Вы можете следовать этим определениям, чтобы получить размер. Ваш файл компоновщика может сильно отличаться от этого, хотя, как я уже сказал, очень сложно дать общий ответ.

  1. Как определить, требуется ли больший размер стека для задач?

В новых версиях IAR есть отличная утилита, которая может определить глубину стека, необходимую для любой функции. В настройках проекта в разделе "Линкер" на вкладке "Дополнительно" можно установить флажок "Включить анализ использования стека". Когда вы включите это, ваш файл карты будет содержать корневые функции и их максимальную цепочку вызовов. Например, мой MainTask выглядит так:

Uncalled function
  "MainTask" in main.o [1]: 0x0000ac41
  Maximum call chain                            *?* 396 bytes

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

С этим инструментом следует отметить, что если вы используете указатели на функции и косвенные вызовы, IAR не может автоматически определить, к чему они ведут. Есть набор pragma директивы, которые можно использовать, чтобы указать, какие возможные функции вызываются в косвенной точке вызова, и вам нужно будет их вставить, чтобы получить 100% точную глубину стека.

Альтернативой является запуск программы на вашем оборудовании, но пусть ОС отслеживает переполнение стека. У Micrium есть страница об обнаружении переполнения стека здесь: Обнаружение переполнения стека задач. Кроме того, вот документация по функции для получения информации об использовании стека задачи: OSTaskStkChk ()

Другие вопросы по тегам