Understanding uxTaskGetStackHighWaterMark results

photon209 wrote on Wednesday, July 17, 2019:

I’m attempting to balance the stack use on my PIC32 by using the High Water mark function to let me know what is left of each of the stacks. Most of them make sense - except the TCPIP stack.
Berlow is the code as I create my tasks:

void SYS_Tasks ( void )
{
/* Create OS Thread for Sys Tasks. */
xTaskCreate((TaskFunction_t) _SYS_Tasks,
“Sys Tasks”,
170, NULL, 6, NULL);

/* Create task for System Timer state machine*/
/* Create OS Thread for GFX_STACK Tasks. */
xTaskCreate((TaskFunction_t) _GFX_STACK_Tasks,
            "GFX_STACK Tasks",
            100, NULL, 7, NULL);


/* Create task for System Timer state machine*/
/* Create OS Thread for LIBARIA Tasks. */
xTaskCreate((TaskFunction_t) _LIBARIA_Tasks,
            "LIBARIA Tasks",
            1024, NULL, 5, NULL);

/* Create task for TCPIP state machine*/
/* Create OS Thread for TCPIP Tasks. */
xTaskCreate((TaskFunction_t) _TCPIP_Tasks,
           "TCPIP Tasks",
            1180, NULL, 1, NULL);

/* Create OS Thread for APPTCPSRVR Tasks. */
xTaskCreate((TaskFunction_t) _APPTCPSRVR_Tasks,
            "APPTCPSRVR Tasks",
            220, NULL, 4, NULL);

/* Create OS Thread for ANYBUSAPP Tasks. */
xTaskCreate((TaskFunction_t) _ANYBUSAPP_Tasks,
            "ANYBUSAPP Tasks",
            200, NULL, 2, NULL);

/* Create OS Thread for SONARTRACAPP Tasks. */
xTaskCreate((TaskFunction_t) _SONARTRACAPP_Tasks,
            "SONARTRACAPP Tasks",
            256, NULL, 3, NULL);

/**************
 * Start RTOS * 
 **************/
vTaskStartScheduler(); /* This function never returns. */

in each task I print out the results of the High Water mark function, for example:

static void _SONARTRACAPP_Tasks(void)
{
UBaseType_t uxHighWaterMark;

while(1)
{            
    SONARTRACAPP_Tasks();
    vTaskDelay(25 / portTICK_PERIOD_MS);
               
    uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );

    if (uxHighWaterMarkPrev[10] != uxHighWaterMark)
    {
        uxHighWaterMarkPrev[10] = uxHighWaterMark;
        SYS_CONSOLE_PRINT("TaskStack: _SONARTRACAPP_Tasks: %u\n\r", uxHighWaterMark);
    }
}

}

    so it only prints out if there is a change...
    
I've tried to reduce everything as much as possible.  And I get the following numbers:

TaskStack: _SYS_Tasks: 42
TaskStack: _GFX_STACK_Tasks: 30
TaskStack: _ANYBUSAPP_Tasks: 34
TaskStack: _APPTCPSRVR_Tasks: 78
TaskStack: _SONARTRACAPP_Tasks: 56
TaskStack: _TCPIP_Tasks: 862

A little buffer for each, BUT if I attempt to reduce the TCPIP task to anything below 1180 the code will stop.

Why does uxTaskGetStackHighWaterMark return a number like 862? If I understand that number, I should be able to reduce the TCPIP task’s stack quite a bit, but if I do the code stops.

I’m pretty early on in my development, so if I need to play games already with space I’m concerned.

My total heap size is 57060

Are there other settings I should be concerned about?

Any advice on this? Thanks!
-Ed

aggarg-aws wrote on Thursday, July 18, 2019:

You are right that uxTaskGetStackHighWaterMark returns the amount of free stack space there has been (in words rather than bytes) since the task was created. Given the you are getting 862, you should be able to reduce the stack.
We need to understand why the code stops? Would you be able to break it in debugger and see where is it stopping?

-Gaurav

richarddamon wrote on Thursday, July 18, 2019:

One possibility is that TCPIP stack might have a 800 some byte array at the bottom of the stack that isn’t actually written to, so the High water mark doesn’t see it, but checking the stack pointer when swapping the task out does see the usage and asserts, (One thing to check is where does the system stop, is it in an assert, and if so what is the assert),

aggarg-aws wrote on Thursday, July 18, 2019:

That’s a good suggestion. For everyone’s benefit, here is the documentation about to how to check for stack overflow: https://www.freertos.org/Stacks-and-stack-overflow-checking.html

Thanks.

photon209 wrote on Thursday, July 18, 2019:

I’d like to know where the code is stopping. I’m using MPLABX and when the ‘halted’ message appears in the debugger and I click the pause there is no indication of where the code has stopped. I also have a breakpoint set at the general exception handler, but it’s not stopping there. odd. The crash doesn’t seem to be caused by an event other than startup - not a new connection or something. So just normal startup, which just shows the TCP stack with 800 words free.

rtel wrote on Thursday, July 18, 2019:

Can you view the program counter in the debugger to at least see where
the code stopped, if not where it crashed.