Before calling the scheduler if I am calling a function means that uses MSP as stack pointer in system stack. If from the task I am calling one function means that uses PSP as stack pointer and it uses rtos taks’s stack right?
Then after calling scheduler program will not use MSP anymore is that correct?
Your question is unclear. The scheduler is never “called,” but is is invoked by FreeRTOS in response to synchronous or asynchronous events. Scheduling is completly transparent to tasks by definition.
Also, what hardware platform are we talking about? The exact usage of stack pointers depends on the MCU used and possibly the port.
For Cortex-M MCUs MSP is used in main before scheduler is started and is reset by FreerRTOS on start of the scheduler to free up maybe used space (in main ) for ISR usage later on. Means MSP is exclusively used for ISRs and PSP is used for tasks in a running FreeRTOS application.
And it also means that you can’t use stack allocated (automatic) variables in main for e.g. task arguments. They would get lost/corrupted due to reset of MSP.
main()
{
int parameter = 42;
ReturnValue = xTaskCreate( …, (void*)¶meter, … );
…
vTaskStartScheduler(); // parameter variable on main stack gets lost because MSP is reset !
for ( ;; );
}
My understanding is this was done to maximize the space for the ISR stack, more important in the past when RAM might be scarce. Sometimes I have wondered if it might make sense to have an option to keep the main stack and start the ISR stack where it ended.
There are pros like not wasting RAM and guaranteeing a main stack to ISRs as specified (usually in the linker file) regardless of any setup code in main and cons like breaking somehow the C-runtime environment rules by surprisingly ‘loosing’ automatic/stack variables in main even if they look like being alive/in scope.
But starting the scheduler is not just a function call even if it looks like that..
The word “reset” here does not mean that the main stack memory is freed (or somehow made unavailable). It just means that whatever was pushed on the stack in main is popped out so that the complete stack is available to ISRs.
To be splitting hairs in two: The stack contents are not popped (that would require every pending function call during system startup to return). The stack pointer is just reset to its startup location so that ISRs will overwrite whatever has accumulated on the startup stack once the scheduler has started.
Does not change anything about the behavior, though.