Stack over flow

Hi,
I’m using FreeRTOS for the first time on a STM32F411 and used an example from the Arduino ide as a starting point.

I have it running mostly ok with two tasks, one which takes care of a websocket server and another which does background task processing.

It will run indefinately but when I add a simple function to detect a button press it’s crashes immediately the button is pressed and the led flashes 4 time indicating a stack overflow.

The button generates an IRQ

void set_pressed()
{
BaseType_t taskYieldRequired = 0;
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();

// If interrupts come faster than 300ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 300) 
      {      
          set_event_flag = true ;                                
      }

last_interrupt_time = interrupt_time;
taskYieldRequired = xTaskResumeFromISR(TunerControlHandle);
taskYieldRequired = xTaskResumeFromISR(WebsocketHandle);

}

I created the tasks as per below:

xTaskCreate (TaskWebsocketRxRead , (const portCHAR *)“DigitalRead” , 8192 , NULL, 1 , &WebsocketHandle );
xTaskCreate (TaskTunerControl , (const portCHAR *) “AnalogRead” , 16384 , NULL , 3 , &TunerControlHandle );

I only have

#include <STM32FreeRTOS.h>

in use and I’m not sure what and where I should change to increase the stack size for either task.

This problem has only arisen as I’ve added more code so pretty sure its a stack overflow issue.

Hopefully I can learn from some experts here and fix what I’m doing wrong.

Regards Tim

Ok the above post is erroneous and the stack overflow is not caused by the button press or irq etc.

But I’d still like to understand how adjust the config setting for stack size and heap etc as there seems to be several of them and I’m not convinced which one is actually used.

I’ve read the documents as best I can but the if / endif’s seem to loop back to the original statement.

Regards Tim

Stack Size for a task is set with the third parameter to the xTaskCreate call. Their are config file settings for the tasks that FreeRTOS automatically creates, since you don’t make those calls yourself, but the parameters in the FreeRTOSConfig.h header are used when FreeRTOS makes those tasks.

Heap size depends on which heap system(s) you are using. The heap1/2/4/5.c files will use the parameters in FreeRTOSConfig.h to set their size. If you use heap3 or malloc for your heap, that size is set by your implementation (often taking all free memory).

Thanks for the reply and confirming how to set stack size - seems as though I got that bit right at least. But I did just guess at the size required.
I still suspect I need to configure the heap and using heap3 would seem to be the best as far as I can tell.

Free RTOSConfig. h contains

#ifndef _ARDUINO_FREERTOS_CONFIG_H
#define _ARDUINO_FREERTOS_CONFIG_H

/* Application specific configuration options. */
#if __has_include(“STM32FreeRTOSConfig.h”)
#include “STM32FreeRTOSConfig.h”
#else
#if __has_include(“STM32FreeRTOSConfig_extra.h”)
#include “STM32FreeRTOSConfig_extra.h”
#endif
#include “FreeRTOSConfig_Default.h”
#endif

#endif /* _ARDUINO_FREERTOS_CONFIG_H */

which in my case points to FreeRTOSConfig_Default.h

which contains the section:

/* Begin custom definitions for STM32 /
/
Define memory allocation implementations to use:

  • 1 to 5 for heap_[1-5].c
  • -1 for heap_useNewlib_ST.c
  • Default -1 see heap.c
    */
    //#define configMEMMANG_HEAP_NB 3

so I figure I’d simply uncomment the line above and rebuild - so far so good.

Thanks again

Tim

Stack sizing is often an inexact science. Some compliers can sometimes give you a stack usage for a function, and that can be used for the task function to determine how much stack is needed, other times you need to estimate it yourself, add a bit of safety margin, then run the system and after a while look at the “high-water” marks of you tasks to see if you were excessive (or short) anywhere.

It looks like your development platform is doing a bit “behind your back” to setup some of the settings, which means you may need to read their documentation (or look at the code) to figure out how those pieces work. I tend to prefer to strip out that sort of “help” so I know what is going on, but that does mean I need to know the system better.

As far as the heap, heap_3 uses malloc, with code to make pvPortMalloc safe, but might not make malloc itself “safe” to use. The option for heap_useNewlib_ST.c might be a version that adds the needed functions to make malloc itself safe to use which is preferable. If this file defined functions like __malloc_lock() and __malloc_unlock then that is what it is doing, which is my perferred solution (if you malloc uses them).

The default or heap 4 should be good too in your case. How did you figure out that you are observing an stack overflow?

Hi
thanks for the comment on heap 4.

When my device (Blackpill F411) stops responding and crashes the led starts to flash slowly - which I understand is an indication of stack overflow.

Regards Tim

I am not familiar with that particular device, but I strongly suspect that your system has crashed, for which a stack overflow is a rather common but by far not the only cause. That means that you need to go through the usual debug techniques to encircle and solve the cause. It is rather unlikely that the pill is able to distinguish stack overflows from other malfunctions and thus signal differently (I might be wrong though).

How did you make that conclusion? What is the code that you are running on the device?

I’ve been working hard on this code and it’s now stable. The crash was being caused by a function corrupting a variable causing the task to crash so likely not a stack over flow.

1 Like

Thank you for reporting back.