Stack memory

A stack is used for function-scoped storage. Each time a function is called, information for that function (like its parameters and local variables) are placed onto a stack. When the function exits, all of the information that was placed onto the stack is removed (this is why passing pointers to local variables is a problem). In FreeRTOS, each task has its own private stack whose size is determined when the task is created.

Since stacks have such an orderly way of being accessed, it isn't possible for them to become fragmented, like a heap. It is possible, however, to overflow the stack by placing more information onto it than its size allows.

On the Cortex-M, there is also one additional stack—the main stack. The main stack is used by ISRs and the FreeRTOS kernel. The kernel and ISRs execute in a privileged mode that modifies the main stack pointer (MSP). Tasks execute on the process stack and use the process stack pointer (PSP). All of the stack pointer operations are taken care of by hardware and the kernel depending on whether the kernel, interrupt, or task (process) is currently being executed. It is not something that users of the RTOS API will normally need to worry about.

Initialization of the stack and heap takes place in Chapter_*startupstartup_stm32f767xx.s. The exact size of the main stack is defined in the linker script STM32F767ZI_FLASH.ld. If necessary, the size of the stack and heap available to the system before the FreeRTOS scheduler is started can be adjusted by modifying _Min_Heap_Size or _Min_Stack_Size:

_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */

It is best to try and keep these both to minimal sizes since any RAM used here will be unavailable to the tasks. These stacks/heaps are only for code that is run before the scheduler is started, as well as the ISRs. This is not the same stack that is used by any of the tasks.

Occasionally, you may run into a problem where you'll need to run some memory-intensive initialization code (the USB stack is a good example of this). If the initialization functions are called outside of a task (before the scheduler starts), then they will use the main stack. In order to keep this stack as small as possible and allow more memory to be used for tasks, move memory-intensive initialization inside a task This will allow the RTOS heap to have the additional RAM that would have gone unused after initialization had the main stack size been increased.

The FreeRTOS kernel manipulates the process stack pointer (PSP) to point to the task stack that has context (is in the running state).

For the most part, you won't need to be immediately concerned with the various stack pointers—they are taken care of by the kernel and C runtime. If you happen to be developing code that will transition between an RTOS and bare metal (that is, a bootloader), then you will need to understand how/when to properly switch the current stack pointer.

The most important thing to keep in mind with stacks is that they must be adequately sized to hold all of the local variables that a task will execute for the deepest call level. We'll discuss ways of getting a handle on this in the Keeping an eye on stack space section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.41.214