Why each task needs a seperate stack?

wendyzhu77 wrote on Sunday, November 07, 2010:

Forgive me for this simple question, but I am new to tFreeRTOS.  The FreeRTOS system seems to require that each task has its own stack, which is 85bytes minimum.  So If I have multiple tasks, the memory usage is sort of large.
I am wondering, why each task needs a seperate task?  My understanding of FreeRTOS schedules tasks based on priority, and higher priority task always interrupts lower priority tasks.  So when a task is executing, only a higher priority task would preempt it and the higher priority task would execute until it finishes (or preempted or even higher ones).  This scheme seems similar to the  general interrupt scheme, so only one stack would suffice the need.  Is it correct?
The possibility for requiring multiple stack seems only to be when a higher priority task is blocked/suspended and willingly yield the processor to other processes (i.e., the lower priority ones).  So is it true that if the process don’t block or suspend one stack would suffice?
Can anyone illustrate why multiple stacks is a must?  Thank you very much!

edwards3 wrote on Sunday, November 07, 2010:

FreeRTOS is a fully preemptive system that uses the stack to store the context of each task individually. Interrupts run to completion so do not have an execution context across calls. I suggest reading the ‘how FreeRTOS works’ section of the website.

richard_damon wrote on Sunday, November 07, 2010:

The higher priority task doesn’t run till it is “finished” but until it blocks (waiting on a queue, semaphore or mutex, or executes a delay). At that point a lower priority task will start up. This switching back and forth is why each task needs its own stack.

In general, tasks rarely “finish”, almost every task will be an infinite loop with a wait for resource somewhere in the loop.

If you want to avoid the stacks, you could look at the co-routines, there are a few restrictions on what they can do, and in exchange for that, they all share the same stack.

wendyzhu77 wrote on Monday, November 08, 2010:

Thanks for your awesome replies.  In my current system I have a fair number of periodical tasks that needs to be executed at different frequencies.  If I assign tasks according to their execution frequencies, I would need to have one task for each frequency, e.g., 1 task for 10ms functions, 1 task for 30ms functions, etc, , then it seems I might ended up with a large number of tasks and the memory consumption seems larger than I like. If they are all in one task, then they will not be preempting and loses the purpose of RTOS.  Is there any solution to this?  I am thinking about Rate Monotonic scheduling so that only one stack is needed (without using blocking calls, and this might make the design a little bit harder…).   Any ideas?

richard_damon wrote on Monday, November 08, 2010:

It sounds like co-routine might be a good fit for you. If all/most of your tasks just need for one signal to start (like a timer) and then just run till they produce a result, it should fit well. To allow the sharing of the stack, co-routines can’t remember anything on the stack when they block (and the block can’t be is a subroutine of the task, it needs to be in the main task loop), but that shouldn’t be a problem for you the way you have described things. Co-routine CAN be interrupted by a higher priority co-routine, but they don’t round-robin at same priority level (except at block/yeild points).