ESP32 Stack configuration (reloaded)

Hi everybody,
is there in the meantime an answer to this question which has already been posted by @mchacher?
-ESP32 Stack configuration
I’m working on a Arduino framework Esp32 project where I am posting data to the Azure Storage Table service.
My application for the Esp32 is working with http requests but it crashes when I try to use TLS secured transmission using the WiFiClientsecure library.
My App crashes when it is performing a POST command with the debugger message: ‘ERROR A stack overflow in task loopTask has been detected’. The stack overflow seems to happen somewhere in the mbedtls sha512 calculations.
My App starts with a free Stack of about 7880 bytes, when my program reaches the POST command there are about 2828 bytes of free Stack left.
Analyzing another example program which is using the WiFiClientSecure library I could find out that at least about 4300 bytes of free Stack are needed to successfully perform a TLS secured request.
The easiest way to solve this problem would be a larger Stack size.
Is there a way in PlatormIO (e.g. in platformio.ini) to configurate a larger stack size.
Thanks in advance
RoSchmi

As for the ESP32, a FreeRTOS task is created that runs setup() and loop(). That task has a certain stack size.

The CONFIG_ARDUINO_LOOP_STACK_SIZE comes from the preconfigured ESP-IDF base

So unfortunately you can’t override it with build_flags = -D CONFIG_ARDUINO_LOOP_STACK_SIZE=16384 in the platformio.ini because this define hardcodes it without checking if it’s previously defined.

So you should first try and edit it C:\Users\<user>\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\config\sdkconfig.h, recompile the application and see if it still fails. If it works, you can manage it more cleanly with a on-the-fly patch and a tiny bit of scripting.

2 Likes

Thanks a lot
your suggestion to change the sdkconfig.h file was working. My App is now running with https requests.
I got a free Stack at start of setup() of now about 16068 bytes.
I will try the ‘on-the-fly patch’ tomorrow.

For those who might be interested to be informed about the actually used stack in their applications, here is the my code to estimate the free Stack:

void * StackPtrAtStart;
void * StackPtrEnd;
UBaseType_t watermarkStart;

void setup() {
   void* SpStart = NULL;
   StackPtrAtStart = (void *)&SpStart;
   watermarkStart =  uxTaskGetStackHighWaterMark(NULL);
   StackPtrEnd = StackPtrAtStart - watermarkStart;

  Serial.begin(115200);

  Serial.printf("\r\n\r\nAddress of Stackpointer near start is:  %p \r\n",  (void *)StackPtrAtStart);
  Serial.printf("End of Stack is near: %p \r\n",  (void *)StackPtrEnd);
  Serial.printf("Free Stack near start is:  %d \r\n",  (uint32_t)StackPtrAtStart - (uint32_t)StackPtrEnd);

  .....
  and at every actual place of interest

 void* SpActual = NULL;
 Serial.printf("Free Stack at actual position is: %d \r\n", (uint32_t)&SpActual - (uint32_t)StackPtrEnd);
2 Likes

You can also make dynamic stack size, configurable from your program code, by doing as follows

File ./cores/esp32/main.cpp

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"
#include "Arduino.h"

#ifndef CONFIG_ARDUINO_LOOP_STACK_SIZE
  #define CONFIG_ARDUINO_LOOP_STACK_SIZE 8192
#endif

#define USING_DEFAULT_ARDUINO_LOOP_STACK_SIZE      false

#if !(USING_DEFAULT_ARDUINO_LOOP_STACK_SIZE)
//KH
// Have to use in your code as follows
// uint16_t USER_CONFIG_ARDUINO_LOOP_STACK_SIZE = 16384;
#warning Using USER_CONFIG_ARDUINO_LOOP_STACK_SIZE, You have to declare USER_CONFIG_ARDUINO_LOOP_STACK_SIZE in your code
extern uint16_t USER_CONFIG_ARDUINO_LOOP_STACK_SIZE;
//////
#endif

TaskHandle_t loopTaskHandle = NULL;

#if CONFIG_AUTOSTART_ARDUINO

bool loopTaskWDTEnabled;

void loopTask(void *pvParameters)
{
    setup();
    for(;;) {
        if(loopTaskWDTEnabled){
            esp_task_wdt_reset();
        }
        loop();
        if (serialEventRun) serialEventRun();
    }
}

extern "C" void app_main()
{
    loopTaskWDTEnabled = false;
    initArduino();
    
    
    
#if USING_DEFAULT_ARDUINO_LOOP_STACK_SIZE
    // Original
    xTaskCreateUniversal(loopTask, "loopTask", CONFIG_ARDUINO_LOOP_STACK_SIZE, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
#else
    if (USER_CONFIG_ARDUINO_LOOP_STACK_SIZE < 8192)
      USER_CONFIG_ARDUINO_LOOP_STACK_SIZE = 8192;
    else if (USER_CONFIG_ARDUINO_LOOP_STACK_SIZE > 32768)
      USER_CONFIG_ARDUINO_LOOP_STACK_SIZE = 32768;
      
    xTaskCreateUniversal(loopTask, "loopTask", USER_CONFIG_ARDUINO_LOOP_STACK_SIZE, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
#endif    
}

#endif

then in your program code

void * StackPtrAtStart;
void * StackPtrEnd;
UBaseType_t watermarkStart;

#if !(USING_DEFAULT_ARDUINO_LOOP_STACK_SIZE)
  uint16_t USER_CONFIG_ARDUINO_LOOP_STACK_SIZE = 16384;
#endif

void setup()
{
  void* SpStart = NULL;
  StackPtrAtStart = (void *)&SpStart;
  watermarkStart =  uxTaskGetStackHighWaterMark(NULL);
  StackPtrEnd = StackPtrAtStart - watermarkStart;

  Serial.begin(115200);
  delay(2000);

  Serial.printf("\r\n\r\nAddress of Stackpointer near start is:  %p \r\n",  (void *)StackPtrAtStart);
  Serial.printf("End of Stack is near: %p \r\n",  (void *)StackPtrEnd);
  Serial.printf("Free Stack near start is:  %d \r\n",  (uint32_t)StackPtrAtStart - (uint32_t)StackPtrEnd);
}

void loop()
{
  // put your main code here, to run repeatedly:
  void* SpActual = NULL;
  Serial.printf("Free Stack at actual position is: %d \r\n", (uint32_t)&SpActual - (uint32_t)StackPtrEnd);
  delay(60000);
}

By changing USER_CONFIG_ARDUINO_LOOP_STACK_SIZE value, you can change the loop() stack size without the need to modify the ./tools/sdk/esp32/include/config/sdkconfig.h every time you need to change.

This is good for testing many different programs and see which stack size is the best fit for each.

1 Like

Many thanks @khoih.prog, I took over your patch in my application
-GitHub - RoSchmi/AzureDataSender_Esp32: Sending sensor data to Azure Storage Tables using board Esp32

2 Likes

Hi @RoSchmi , sorry for bothering you. I tried to do the posted solution, but I won’t change my free stack no matter which number I put. Is there something that I could be missing?

I nuked Vscode and reinstalled everything from 0. It works now, thx my guy

1 Like

For anyone who comes here having the same question, nowadays it is possible to set the stack size here