Facing what probably is a real noob problem. Posting it here in the hope that it’ll be such an ordinary thing that the guys in the know will just click on it. If not, well I be slogging on…
I’m working with a Microchip PIC32 MCU, using the FreeRTOS port available on the site.
The problem is that my app will crash with a stack overflow for no good reason that I can discern.
The application has a serial port handler, for RX and TX both.
The interrupt routine (copied from the FreeRTOS demo example) is a simple wrapper, looks like this:
i.e. context should be properly saved and restored upon entry/exit to this routine.
The vU2InterruptHandler() function calls RX and TX handlers.
The RX handler posts the received character into a queue, performing a TaskYIELD() if a higher priority tasks has been woken by the post.
The TX handler reads a global circular buffer and xmits any characters it finds there. No TaskYIELD() is performed from the TX handler, on the theory that it isn’t needed since FreeRTOS is never called from it.
Mostly it works, but once in while (rather too often, really) the application crashes from the vTaskSwitchContext() kernel function into the stack overflow hook routine. Examining the current TCB it is clear that the top-of-stack is much smaller than the stack base – a stack overflow condition *does* prevail.
However, the top-of-stack value recorded in the current TCB appears to belongs to another task altogether.
Examining the stack memory for the crashed task one can see that most of it has never been in use – out of a 256 item stack I’d get a high water mark of 150 or so, yet the top of stack is 100 items or so *below* the stack base.
Clearly the wrong top-of-stack value is being written into the current PCB, for whatever reason. The usual suspect is --of course-- some interrupt routine, more than likely the serial TX one since the program does copious amounts of 115 kbaud RS-232 output during its processing.
Is this a familiar scenario to you folks?