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.
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);
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.
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
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
For anyone who comes here having the same question, nowadays it is possible to set the stack size here