FreeRTOS-Kernel icon indicating copy to clipboard operation
FreeRTOS-Kernel copied to clipboard

[Feature Request] Stack overflow checking of MSP on Cortex-M

Open tajen opened this issue 3 years ago • 7 comments

Is your feature request related to a problem? Please describe. There are stack overflow check for all task stacks. But for, at least some, ARM Cortex-M MCUs there is a separate stack for exceptions/ISR. This stack is never checked for overflow.

Describe the solution you'd like Ideally it would just be part of the normal stack checking. But I am unsure if it can be made to work with all targeted MCUs.

Describe alternatives you've considered Alternatively, @drnadler (link) made some effort to implement it along with some other stuff regarding STM and newlib.

Additional context None

tajen avatar Jan 31 '22 13:01 tajen

This is something that is hard to implement generically. One way could be to use MPU to catch MSP overflows. You can use a block of memory for main stack and put a red block right after it. The red block is blocked all access using MPU and any access to it will result in memory fault.

aggarg avatar Mar 01 '22 01:03 aggarg

How about doing it in the STM32 port when doing context switch in xPortPendSVHandler, and just checking the MSP stack in the same way as taskCHECK_FOR_STACK_OVERFLOW() checks the task stack?

Basically deriving from @DRNadler and add the overflow checking in the task switching

tajen avatar Mar 01 '22 08:03 tajen

The same Cortex-M3 port runs on all Cortex-M3 and M4 devices, and the same Cortex-M4F port runs on all Cortex-M4F and M7 devices - so there is no separate STM32 port. That means there is a big issue in regards to portability as the kernel has no way of knowing where the end of the MSP stack is. Some linker scripts define it explicitly, whereas others just set the start of the stack to the top of ram and let it grow until it hits something. We can do overflow checking in a portable way on the task stacks because the kernel creates the stack (or is passed in the stack if created statically) so it knows where both extremes are.

RichardBarry avatar Mar 01 '22 19:03 RichardBarry

As Richard explained, we do not have a separate STM32 port. If you want to do it for your application, you can possibly use traceTASK_SWITCHED_OUT macro and put a check for MSP overflow there?

aggarg avatar Mar 02 '22 02:03 aggarg

The same Cortex-M3 port runs on all Cortex-M3 and M4 devices, and the same Cortex-M4F port runs on all Cortex-M4F and M7 devices - so there is no separate STM32 port

My mistake, of course there is no STM32 port - What I meant to say was the Cortex-M ports.

That means there is a big issue in regards to portability as the kernel has no way of knowing where the end of the MSP stack is.

You would have to define a maximum MSP Stack size. It could be in the linker script. But for this purpose it would have to be in the FreeRTOS config. It will only be used for overflow checking anyway

... others just set the start of the stack to the top of ram and let it grow until it hits something.

And this is really the issue. At the moment you can enable stack overflow checking. But it does not check every/all stacks, so you might have a stack overflow you didn't know about.

I am not sure if all Cortex-M4F/M7 has MSP stack, but I imagine so. In that case, I don't see the problem in adding a configMAX_MSP_STACK_SIZE (or whatever) and check the MSP stack in xPortPendSVHandler. If this is not the case - then I agree, it becomes difficult to port.

If you think it completely impractical I will have to resort to using the trace macro as @aggarg suggests. I can also propose a solution in a pull-request if it helps?

tajen avatar Mar 04 '22 08:03 tajen

You would have to define a maximum MSP Stack size. It could be in the linker script. But for this purpose it would have to be in the FreeRTOS config. It will only be used for overflow checking anyway

For overflow checking to be meaningful, the defined size should be correct i.e. the defined size should be size of main stack. As Richard mentioned, many times that is not defined and MSP is allowed to grow in the remaining RAM.

aggarg avatar Mar 04 '22 09:03 aggarg

For overflow checking to be meaningful, the defined size should be correct ...

I don't see how it can be incorrect

... i.e. the defined size should be size of main stack ...

The main stack is just as well defined as the MSP stack

... many times that is not defined and MSP is allowed to grow in the remaining RAM.

And this is the problem - you have no way of knowing if it is growing into used RAM.

It is up to the user to define a maximum MSP stack size, just as with every task stack. There is really no difference.

Even if an MSP stack size is defined in the linker script. FreeRTOS /* Set the msp back to the start of the stack. */ in prvPortStartFirstTask(). Which will most likely make the definition in the linker script useless.

The thing that does help is, that the MSP stack can grow, without problem, until it runs out of unused memory, whereas for the task stacks, they will cause problems as soon as they overflow the stack with just a single byte.

I think I will propose a solution, and we can discuss it from there.

tajen avatar Mar 04 '22 20:03 tajen

We look forward to a solution so we can discuss the specifics of MSP stack checking. Closing this issue.

n9wxu avatar Feb 23 '23 17:02 n9wxu