A few weeks ago a discussion on stack size came up (FRDM-K22F monitoring maximal stack/heap usage of program) with some pointers as to how to see how much stack is being used at a given time but there really weren't good instructions in understanding how to calculate the maximum memory required by a FreeRTOS task stack to cover all contingencies.
The Task Award Debugging (TAD) "Task List" is useful as are the other tools that @ErichStyger has pointed out in his excellent MCU On Eclipse series but they give an idea of what's happening in regards to the task's stack, but do not give you a hard and fast indication if you've blown the stack.
This has been an issue for me because in my current application, I could see some strangeness but I couldn't quantify it. Sometimes tasks would stop responding and/or the aptly named task "ied" would appear in the Task List. Unfortunately, this would only appear after 9+ hours of very rigorous testing.
I suspected that the problem was a task with a blown stack as there could be a case where multiple interrupt requests could pile up during a Flash erase/write cycle in which interrupts are disabled. This results in multiple simultaneous interrupt requests being serviced simultaneously and the context information for each instance being placed on a task's stack.
After doing some research, I found that the task stacks can be checked to see if they have gone beyond their defined limits by setting the "configCHECK_FOR_STACK_OVERFLOW" macro in "FreeRTOSConfig.h" to "2". "1" can also be used as a value for this test, but "2" provides a more complete test (the stack area is initialized to 0xa5a5a5a5) and if a new maximum value is detected, the next four words are checked for 0xa5a5a5a5 and if there is a miscompare, it is assumed that the stack pointer has gone beyond its defined limits and calls the "vApplicationStackOverflowHook" method.
"vApplicationStackOverflowHook" is a user provided method which handles the overflow event. I've created a simple one in the "overflowCheck.c" file in which interrupts are disabled, indicator LED(s) are set to a specific pattern and the code enters a hard loop.
/*
* overflowCheck.c
*
* Created on: Apr. 13, 2021
* Author: myke
*/
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MK22F51212.h"
#if (2 != SDK_DEBUGCONSOLE)
#include "fsl_debug_console.h"
#endif
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
void vApplicationStackOverflowHook(TaskHandle_t* pxTask
, char* pcTaskName ) {
__disable_irq();
GPIO_PinWrite(BOARD_OVERFLOWLED_GPIO
, BOARD_OVERFLOWLED_PIN
, LOGIC1);
for(;;) { }
}
Note that the LED operation uses the "GPIO_PinWrite" inline method which should not access the stack (as the stack is unreliable at this point). I'm making this point becasue the "vApplicationStackOverflowHook" method is only called when the stack is blown - execution must not continue past this point as you are dealing with unknown application and system variable values.