If you are running the latest version of IAR EWARM, there is a built in tool that you will find very helpful with these questions.
For your first question, you will need to search in the map file for the name of each task's stack. In this case, the map file isn't that helpful, as you would likely be better off searching your project for the CPU_STK
type, as that will give you results with all properly defined stacks. If you do look in the map file, you may see a line like this:
MainStack 0x20000000 0x1000 Data Lc main.o [1]
This means that MainStack
(presumably a stack for a MainTask
) is sized as 0x1000 or 4096 bytes. The first column is symbol name, the second is location in the address space, the third is size, the fourth is type (Data, Code), the fifth is scope (Lc = local, Gb = Global), and the last column is object module it is located in.
If instead you search the project for instances of CPU_STK
you would find the following:
static CPU_STK MainStack[4096];
This gives you the same information that MainStack
is size 4096, but by searching for CPU_STK, it will also give you results for other tasks, so you may actually see the following in your results:
static CPU_STK MainStack[4096];
static CPU_STK AuxStack[512];
So, now you can see that there's also an AuxStack
(presumably for an AuxTask
), and it is 512 bytes. This would require to searches in the map file for specific stack names to get results, so I would find this easier.
For this one, you'll want to dig into either the linker configuration file, or the linker section in the options. The easier way is through the options. Go to your project options, and then the Linker item on the left. Under the configuration tab, select Edit..., and then go to the Stack/Heap tab. This will give you easy access to the sizes that IAR will use to allocate the HEAP and CSTACK memory regions in the linker.
Alternatively, you can dig into the .icf
file and you may find a set of lines like so:
/*-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__ { };
It could also look completely different! It's hard to give a generalized answer for this one, so you're best off looking in the options. In the code above, though, you can see CSTACK
and HEAP
have their sizes defined by the symbols defined earlier in the file. You can follow these definitions to get the size. Your linker file could be very different from this, though, so as I said, it's really hard to give a general answer.
Newer versions of IAR have a great utility that can determine the stack depth required by any function. In project options, under Linker in the Advanced tab, you can check "Enable stack usage analysis". When you enable this, your map file will contain root functions and their maximum call chain. For example, my MainTask
looks like this:
Uncalled function
"MainTask" in main.o [1]: 0x0000ac41
Maximum call chain *?* 396 bytes
So, this is telling me that MainTask is an uncalled function (which it is not called directly, but by function pointer, which IAR cannot resolve automatically), and it requires 396 bytes of stack. Below it, it will show you the call chain that adds up to 396 bytes.
Of note with this tool is that if you use function pointers and indirect calls, IAR cannot automatically figure out where these lead. There are a set of pragma
directives that can be used to tell it what possible functions are called at an indirect calling point, and you'll need to put these in to get a 100% accurate stack depth.
An alternative is to run the program on your hardware, but let the OS monitor for stack overflows. Micrium has a page about detecting stack overflows here: Detecting Task Stack Overflows. Additionally, here is the documentation on a function to get information about a task's stack usage: OSTaskStkChk()