Mark
Mark

Reputation: 5102

How to set the stack depth parameter when creating a task

In ESP-IDF you can create a task with the xTaskCreate() function:

static BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char *constpcName, const uint32_t usStackDepth, void *constpvParameters, UBaseType_t uxPriority, TaskHandle_t *constpvCreatedTask)

and the documentation says:

usStackDepth: The size of the task stack specified as the number of bytes. Note that this differs from vanilla FreeRTOS.

Usually I see examples like this:

void myTask(void *arg);
TaskHandle_t myTaskHandle = NULL;

xTaskCreate(myTask, "myTask", 2048, NULL, 10, &myTaskHandle);

I wondering how to properly select the stack depth (2048 in the example). Since it reserves memory space I bet I cannot just make a blind guess and insert a higher value otherwise I'll run out of memory space.

Reading though the docs I found this other function uxTaskGetStackHighWaterMark() and looking at the return value it should give me an indication about how close I'am to stack overflow for the specified task.

Hence, the only way is to set a "random" value, then check the high-watermark and adjust the stack size according? Is there a compiler function to help me to select a value without guessing?

Upvotes: 0

Views: 178

Answers (1)

satur9nine
satur9nine

Reputation: 15082

Techniques such as function pointers, variable length arrays, alloca, and recursion make it impossible for a static analysis tool to produce a report on the maximum stack size for any given code execution flow.

If you are using VLAs, alloca and recursion you may want to reconsider some of those techniques and/or ensure your code enforces limits on each of those to prevent excessive stack consumption at runtime.

As mentioned in comments and other answers most compilers can tell you stack usage of non-dynamically allocated stack memory for each function that is compiled using a flag like -fstack-usage . However, for that to be useful you still need a really good idea of which functions will be called and how deep the stack will get, and it won't report variable size allocated memory so the stack report is really best used to look for functions that might be memory hogs. See How to determine maximum stack usage in embedded system with gcc?

The best technique I can suggest is make an educated guess (hopefully better than random) on an upper bound stack size (if you really can't think of something try 25% of RAM).

Next, set configCHECK_FOR_STACK_OVERFLOW to 2 and implement vApplicationStackOverflowHook(). See https://www.freertos.org/Stacks-and-stack-overflow-checking.html for details.

Finally running your task through as many expected execution flows as possible and call uxTaskGetStackHighWaterMark() at the end.

If the program hits the limit then make it higher and repeat. Look at the high water mark number when you get it and multiply by some factor for possible variation and future code changes, lets say 1.2x.

Upvotes: 0

Related Questions