Adjusting heap and stack size

The allocation of stack and heap is more complicated when using a RTOS.

Without RTOS, a common solution is to have the stack grow downwards from the top of RAM and the heap grow upwards from the top of statically-allocated RAM. If you pre-fill un-allocated memory with a pattern (e.g. 0xA5A5A5A5) during initialisation, then at run-time you can see how much free memory you have, by counting how many words of that pattern you still have starting from the top of the heap. If your application has some sort of user interface, you can report this value in a diagnostic function.

With RTOS, each task has its own stack area, and for some processors (e.g. ARM) there is a separate interrupt/exception stack. So you normally have to allocate a fixed amount of memory for each of these stacks. To track stack usage, you can use the same trick, i.e. fill each stack with 0xA5A5A5A5 and then search from the bottom of each stack to see how many words still hold that value. FreeRTOS provides option INCLUDE_uxTaskGetStackHighWaterMark to do that for you, for each task; and you can do the same thing yourself for the interrupt/exception stack.

This is what we do in our applications. We have a diagnostic facility that reports (among other things) the number of unused stack words for each task, and the free interrupt/exception stack. We start off using large stacks, then we run the system for a while, use the diagnostics to see how much space is free on each stack, and reduce stack sizes so that the amount of spare stack space is not excessive.

The need for a separate stack for each task is the main thing that prevents use from using as many tasks as we would like to.