2

I have a follow-up question to the one asked here: Main Stack Pointer(MSP) vs Process Stack Pointer(PSP)

I was wondering about how these pointers are managed so that they do not write in the same stack location if stack usage is high. My understanding is that they are both going to point to addresses within the stack that they share so how do both pointer co-exist?

4 Answers4

6

There isn't just one 'stack'.
A stack is not something special, it's just an area of RAM used as a stack.
There can be multiple stacks, and this is almost guaranteed to be the case with any sort of multi-tasking OS - each task has it's own piece of RAM to use as a stack.
Typically with microcontrollers like most of the Cortex M series there isn't anything preventing one task from misbehaving and writing into another task's stack - just as there isn't anything preventing a task from writing to any other RAM location it wants to.
It's the job of the firmware developer to analyze and estimate how much stack space each task needs, and allocate RAM to these stacks appropriately.

brhans
  • 14,373
  • 3
  • 34
  • 49
3

As the answer to that other question suggests, there is in fact more than one stack in the system. There's one stack for the "operating system" (usually an RTOS, but could be something like Linux), and a separate stack for each process/task/thread running in the application code. The OS always uses the main stack pointer (mainly for quick response to interrupts, etc.), and the process stack pointer points to the stack of whichever process is currently running.

When it comes time to switch to a different process, the process state is saved on its stack. Then the PSP is pointed to a different stack and the new process's state is restored from that stack. The stacks do not overlap in any way.

Dave Tweed
  • 168,369
  • 17
  • 228
  • 393
1

There is no mechanism to prevent that. In the end, the person that writes software must make sure to define large enough stacks so a stack growing beyons space reserved for it does not overwrite anything else in the system.

That applies to both the main stack which is generally used by the OS itself and the stack for tasks/processes that are switched into execution by the OS.

The stack area is not shared, they don't point to the same area - you can do so if you insist but in general that's not done. Generally the main stack would exist at the end of RAM (or whatever the programmer selects) and grows downward. The process stacks are generally just somewhere in data area, or allocated from the heap.

Justme
  • 127,425
  • 3
  • 97
  • 261
0

All the answers provides insights on what is a stack and how multiple stacks are used, but not why it is useful.

Typical "big" CPUs that you can find in desktop computers use several stacks, usually one per privilege level, and with the memory management unit (MMU), the OS running at a higher privilege level can protect itself from misbehaving user processes. Having several stacks here simplify memory management with the MMU, because then the OS has its own stack which resides in its dedicated memory region (multi-core systems make the OS use multiple stacks, but it's more or less the same situation). Microcontrolers, on the other hand, don't have a MMU, only possibly a MPU (memory protection unit), and the protection they provide is usually very coarse, and microcontrolers don't usually run full-blown OSes with several processes, but a small RTOS with several threads, with limited protection. Can such an OS work without using a dedicated stack?

Of course it can. In fact, I wrote one simple preemptive RTOS running on PIC18 microcontrollers where the OS stack doesn't use a dedicated region of memory, and it worked well. The problem in doing so is that now every thread's stack have to be big enough not only to hold what is needed for their own computation, but also some more for interrupts and the OS, which means that now all threads must use bigger stacks that would normally be needed. In my case that wasn't too much of a problem, and not switching the stack back and forth saved a few cycles, but it was a memory overhead nonetheless.

Cortex-M cores, with their MSP and PSP stack registers, make the stack switching process seamless and automatic. With proper location of the Main Process Stack (used for the OS and interrupts), you can avoid having a thread be corrupted by an interrupt occurring in a different thread that overrun its stack.

Jarhmander
  • 443
  • 2
  • 7