I'm programming with arduino but i need more stack space

Hi at all… I’m new

I’m writing a program with the ARDUINO IDE but i have a problem of stack overflow due to large structures in a library that i use. I don’t want change the library because i don’t want introduce errors in the code (in particular i need to free() for each malloc()).

I have some questions

  1. How can i increase the stack size for my arduino process?
  2. I’m evaluating to use the idf ide from expressif. Any suggestion for these ide?

I need arround 400k of ram

Here is the code, basically **i call recousevly a function that allocates an array of 10000 bytes. I allocate 10kb intentionally. I tried also to allocate 1kb but the behaviour was more or less the same. Basically the board reset after few calls.

On the raspberry i do not have this behaviour

// Calls a function x times, this functions allocates 1k in the stack
// then i call the function again

void callProc(int x){
  // I allocate around 1kb as local variables then it should go in the stack 
  size_8t vector[10000];
  Serial.print("I have allocated 1kb in the stack");

  // I repeat the allocation, calling recoursivley callProc(x-1) times
  if (x>=2){
    callProc(x - 1);
    // I just add this code to prevent the code optimization on the allocation of my array
    for (int i=0; i<999;i++){
      vector[i+1] = vector[i];
    }
  } else {
    return;
  } 
}

Here you see the output

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13516
load:0x40080400,len:3604
entry 0x400805f0
delay(5000);
Call callfun() in 2000ms
Allocated 1kb: 50 Stack size: 22004
Allocated 1kb: 49 Stack size: 11956
Allocated 1kb: 48 Stack size: 1908
Allocated 1kb: 47 Stack size: 1908
Allocated 1kb: ets Jun  8 2016 00:22:57

Can i have some hints on how increase the stack size of a task and some snipets of code as example?

THanks a lot!

Assuming that you are using FreeRTOS API to create a task, the usStackDepth parameter of xTaskCreate specifies the stack size of the task - This page describes the RTOS xTaskCreate() FreeRTOS API function which is part of the RTOS task control API. FreeRTOS is a professional grade, small footprint, open source RTOS for microcontrollers.

How much RAM does your hardware have?

Why do you need to allocate 1KB array on stack? What is the problem that you are trying to solve? The detailed description of the problem will help us to see if there can be a different/more optimized solution.

Thanks.

Thanks for the reply

My problem is to run a library for encryption that require high amount of memory (around 400k) to be runned. The memory is allocated both in the stack, by local variables, and in the heap, through malloc(). I don’t want modify the library in order to move the memory to the heap because there is HIGH probability to introduce errors in the code.

I’ve tried to run the code on the arduino nano IOT but Ive got no response from the microcontroller. I supposed that it was a problem of memory size and it was. Arduino NANO IOT have only 32k

I’ve tried to use raspberry nano and it worked well and it have around 500k of ram but RaspBerry does not have integrated support for BluetoothLE then i chosed was using an arduino ESP32 because have the same memory size of the RB, around 500k

Then when I’ve tried to flash the code in my ESP32 board with arduino ide, the board return me an error like that

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee

Then i supposed that was again a problem of memory (in particular the stack, every time i call a new function) and i thought how to “analyse” the quantity of memory is present in the stack calling recursevly a function that every times allocates 1k-10k.

In this way i understood that the size of the stack is around 30k. I also found the same behavioir that i had in my main program, the same error. Then the same cause. STACK

I’ve form your explanation understood that i can use the

BaseType_t xTaskCreate(    TaskFunction_t pvTaskCode,
                            const char * const pcName,
                            configSTACK_DEPTH_TYPE usStackDepth,
                            void *pvParameters,
                            UBaseType_t uxPriority,
                            TaskHandle_t *pxCreatedTask
                          );

and specify the size of the stack. But WHERE i should written this code?
In the arduino ide inside the start() or i should use the espressif idf?

I also not understood well the stack (in the sense of architecture) that there bihind the arduino enviroment.

I know that there are many “layers” like that

My application
^^^^^^^^^^^^^^^
Arduino code
^^^^^^^^^^^^^^^
FreeRtos
^^^^^^^^^^^^^^^
Espressif IDF
^^^^^^^^^^^^^^^
My micronontroller

Then IF my model is true I can go to the right level and act consecutivly in order to inclrease my stack.

Hi, I’ve tried the function that you have told me. In particular i’ve tried this code:

void newloop(void* param) {
  while(1) {
    delay(10000);
    Serial.printf("memtask: %d\n", uxTaskGetStackHighWaterMark(NULL));
  }
}

void setup() {
  Serial.begin(115200);
  xTaskCreateUniversal(newloop,"newloop", 64*1024, NULL, 1, NULL, ARDUINO_RUNNING_CORE);
  vTaskDelete(NULL);
}
void loop() {}

The output is 64200, that is correct. But i need MORE than 64k of stack. I need around 350k,

Do you know why when i use the xTaskCreateUniversal(newloop,“newloop”, x*1024, NULL, 1, NULL, ARDUINO_RUNNING_CORE); with x>64 the output is <64k?

Many thanks

FreeRTOS defaults to the stack size being “unsigned” which can be just 16 bits. Later version allowed defining configSTACK_DEPTH_TYPE to make is something bigger.

Can you explain what you mean by this line? Is it that you are not able to allocate stack bigger than 64K? If so, then as @richard-damon pointed out, check the value of configSTACK_DEPTH_TYPE . Also, you can step through the code and check the values at this line - https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/tasks.c#L761

Thanks.

Do you know why when i use the xTaskCreateUniversal(newloop,“newloop”, x*1024, NULL, 1, NULL, ARDUINO_RUNNING_CORE); with x>64 the output is <64k ?

Richard damon has replied to my question. Is a problem of types.

================================================================

I’ve modified the configSTACK_DEPTH_TYPE to uint32_t in the FreeRTOS.h

I’ve red now I’m trying to modify the definiton as adviced but the microcontroller does not respond in this case

xTaskCreateUniversal(newloop,“newloop”, X*1024, NULL, 1, NULL, ARDUINO_RUNNING_CORE);

where X>150.

I need 300k of memorynot only 150

My board is an AZDelivery ESP32-WROOM-32 and has declared 512kb of ram. Bui i’m unable to use

What is meant by that? Do you check the return value of the task create function and see if it is failing to create? If so, you’ll need to look at the memory map and see where the memory is going as ESP puts all the remaining RAM to be used as heap.

Better don’t patch the FreeRTOS sources (FreeRTOS.h).
The right way for configuring/customizing FreeRTOS is doing so in your FreeRTOSConfig.h.
Also note that the stack size used by the FreeRTOS native xTaskCreate function is:

‘usStackDepth The number of words (not bytes!)’

See the xTaskCreate API documentation for details.

xTaskCreateUniversal seems to be Arduino / Espressif specific, but is’s probably just wrapper for FreeRTOS xTaskCreate.
You should check the xTaskCreateUniversal documentation to be sure.

many thanks for the explanation. I’ll check the xTaskCreateUniversal

But where i can find the FreeRTOSConfig.h?

It seems to be a wrapper around xTaskCrerate - arduino-esp32/esp32-hal-misc.c at master · espressif/arduino-esp32 · GitHub

It should be part of your project. I typically have it in my main application folder or a ./config folder it the project is big and has a number of configuration headers. It needs to be on the include path for your project.

It should have been added when you created your project in the IDE, either automatically if it knows about FreeRTOS or by you.

Since FreeRTOS.h includes the file, it has to be there somewhere.

Well, just find the file in your FreeRTOS project source tree. I’m pretty sure it’s there :wink:

The ESP32 Arduino framework allocates the “main” Arduino SETUP/LOOP task with a limited stack size. There are (at least) 2 work arounds.

  1. you can go update the framework. This works but you need to dig and the next time you update the framework your work will be undone.
  2. you can create your own work task in the SETUP function with the stack size you need. You can still do work in the loop() function running in the original task but you will use your new task for the work that needs the giant stack.