I am trying to make a C++ application using C++ wrapper from michaelbecker/freertos-addons (see on github), but there was a problem with local variables of the Thread class in main function. After running the scheduler prvPortStartFirstTask function updates the stack pointer to its initial value and destroys member data of Thread class instances which placed in stack. Is it a bug or a feature?
static void prvPortStartFirstTask( void )
{
/* Start the first task. This also clears the bit that indicates the FPU is
* in use in case the FPU was used before the scheduler was started - which
* would otherwise result in the unnecessary leaving of space in the SVC stack
* for lazy saving of FPU registers. */
// set SP initial value
// __asm volatile(" ldr r0, =0xE000ED08 \n"); /* Use the NVIC offset register to locate the stack. */
// __asm volatile(" ldr r0, [r0] \n");
// __asm volatile(" ldr r0, [r0] \n");
// __asm volatile(" msr msp, r0 \n"); /* Set the msp back to the start of the stack. */
__asm volatile(" mov r0, #0 \n"); /* Clear the bit that indicates the FPU is in use, see comment above. */
// work if comment
__asm volatile(" msr control, r0 \n");
__asm volatile(" cpsie i \n"); /* Globally enable interrupts. */
__asm volatile(" cpsie f \n");
__asm volatile(" dsb \n");
__asm volatile(" isb \n");
__asm volatile(" svc 0 \n"); /* System call to start first task. */
__asm volatile(" nop \n");
__asm volatile(" .ltorg \n");
}
FreeRTOS, in many ports, reuses the main stack as the interrupt stack, and as such any data place on that stack might not be still available after the schedule starts. This has not been considered a bug.
The key is that you don’t want to create the objects on the main function stack, but either on the heap or as static objects.
I agree that the mention isn’t very obvious, but I thought it was mentioned in the port file itself.
You are not the first person to have this problem, but as I remember, it is considered an intentional limitation (to save memory) and not a “bug”.
I agree that it would sometimes be nice to have the option of not overwriting the main stack, and that would also make it possible to implement the end scheduler function, which is out of the question if the stack has been overwritten.
well yes and no. It is a design decision made for resource usage efficiency. One of the things that enables FreeRTOS to run on even very tiny platforms. The pros and cons have been discussed here many many times.
Of course you are free to change it if it offends you, FreeRTOS being open source.
A big benefit of this somewhat special approach is that one can always rely on having the full specified main stack as ISR stack independent of any user code in main.
I consider main as just the FreeRTOS bootloader not being part of the FreeRTOS application itself because the runtime environment resp. model completely changes when starting the scheduler (the OS).
I do not think that this is possible because the decision how this is done is eventually made by the port - some ports may already use a disjoint interrupt stack, so a global configuration would be meaningless for such ports.