FreeRTOS code causes crash on ESP32-S3 board

Maybe you can help me as well. I am trying to get an Adafruit ESP32 S3 TFT board to work with FreeRTOS. I load the Adafruit Feather S3 TFT BSP.

It compiles OK, no errors, but when loading it into the board, I get a hardware crash, and a bootloader display on the LCD screen. The code is listed below.

// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

// the setup function runs once when you press reset or power the board
void setup() {
  
  // initialize serial communication at 9600 bits per second:
  //Serial.begin(9600);
  
  //while (!Serial) {
   // ; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
  //}

  // Now set up two tasks to run independently.
  xTaskCreate(
    TaskBlink
    ,  "Blink"   // A name just for humans
    ,  128  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL );

  xTaskCreate(
    TaskAnalogRead
    ,  "AnalogRead"
    ,  128  // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, LEONARDO, MEGA, and ZERO 
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN takes care 
  of use the correct LED pin whatever is the board used.
  
  The MICRO does not have a LED_BUILTIN available. For the MICRO board please substitute
  the LED_BUILTIN definition with either LED_BUILTIN_RX or LED_BUILTIN_TX.
  e.g. pinMode(LED_BUILTIN_RX, OUTPUT); etc.
  
  If you want to know what pin the on-board LED is connected to on your Arduino model, check
  the Technical Specs of your board  at https://www.arduino.cc/en/Main/Products
  
  This example code is in the public domain.

  modified 8 May 2014
  by Scott Fitzgerald
  
  modified 2 Sep 2016
  by Arturo Guadalupi
*/

  // initialize digital LED_BUILTIN on pin 13 as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
  }
}

void TaskAnalogRead(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  
/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Graphical representation is available using serial plotter (Tools > Serial Plotter menu)
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.
*/

  for (;;)
  {
    // read the input on analog pin 0:
    int sensorValue = analogRead(A1);
    // print out the value you read:
    //Serial.println(sensorValue);
    vTaskDelay(1);  // one tick delay (15ms) in between reads for stability
  }
}

Other software on the module works OK, including all the tried examples, as well as the sample TFT routines.

Any ideas what to try to resolve this?

What have you tried?

I see all the appropriate files in Arduino15 AppData folder (FreeRTOS.cpp and RTOS.h).

I have tried running it on Platform IO (in case it was a corrupted IDE) , but get the same error.

It is supposed to be a functioning library, but unless I am doing something wrong, there must be some kind of incompatibility between the board and the standard library.

Please don't hijack threads @rs77can. I have split your post out to its own topic.

Hijacking is against the Arduino forum rules. The reason is that it may sidetrack the discussion, even preventing the creator of the topic from getting the assistance they need.

This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

vTaskDelay(1) in arduino core is 1 ms not 15 msecs.
So with it having a higher priority than the other task, it is taking nearly all the cpu time.

The program is strictly a cut and paste from online existing sample code. The 15mS may be the tick on older 8MHz Arduinos. The ESP32 CPU is 240 MHz, so 1mS delays should be OK.

However, I changed the code to 10 mS and no change -


the same happens - Arduino equivalent of BSOD

  1. Run the crash report through the Exception Decoder and post the results.
  2. Try increasing the tasks' stack size.

Starving a lower-priority task for CPU time by itself won't cause a crash ... especially not OP's simple code example.

Right. I also have crashes with RTOS and some AdaFruit display libraries on my ESP32 board. Since a different display was working I didn't research the problem further.

It may be a bus matter, the I2C display works like a charm while the SPI display crashes.

My only guess would be the board somehow uses the timer that is used by FreeRTOS, or maybe it changes interrupt vectors??

I posted the problem in the Adafruit forum as well, but have not received a reply yet. I ordered a different board (ESP32 also) with an integrated LCD display that another poster on a different forum said they had success using it with Free RTOS, so I will give that a try also and let the forum know if it worked.

Did you take the steps suggested in Post #7?

I increased the Stack to 512 - but no difference (did not expect to, as I am doing nothing in the tasks that would use up stack)

I am unable to run the exception decoder, and the reason is that the ESP32 S3 seems to not be able to reset via the USB connection.

ESP32-S3 hangs on "Hard resetting via RTS pin..." - adafruit industries

The conclusion from that thread was that this is expected behavior, which makes it impossible to run the exception decoder I believe.

It is also not possible to manually load the COM port, as in my case the upload port is COM4 (which completes the upload, and then hangs on resetting via RTS). I then press Reset, and it crashes immediately, before getting a chance to connect to port COM5.

Your code from Post #1 crashed (with stack exceptions) when I tried it. It ran fine when I increased the stack size to 2000 bytes for each task. I even enabled the Serial.print lines and saw output in the Serial Monitor.

I'm still having trouble understanding exactly what you're seeing. Does a simple "Hello World" sketch print in the Serial Monitor? If nothing prints, how do you know it's crashing?

I've sometimes had trouble opening the Serial Monitor with ESP32 boards. To get around it, leave it closed and do this:

void setup() {
  Serial.begin(115200);
  delay(4000);

After the code uploads and I get the "Hard resetting ..." message, I then open the Serial Monitor during the 4-second delay. Haven't had any problems doing it that way.

Well, that is embarrassing.

I increased it to 2048, and yes it did work.

The serial prints - when present work - I usually open a Putty window.

I guess the ESP32 must need a lot more stack space to save its registers etc. It is a little weird, as on another project using the Portenta H7 (STM32H747) and MBed, I have some tasks that run with a stack size of only 256 bytes, and use only 120 bytes of them when using the runtime monitor.

Thanks for the Debug delay idea - that should be useful in the future.

It's much easier to first get things going without stack exception crashes by using a much larger stack size than needed. After the tasks are running without crashing, you can use the High Watermark functions to see how much space the tasks are actually using and trim back on the amount allocated to them. But don't try to cut it to the bone, I like to leave ~200 bytes of buffer "just in case"

How about the watchdog ? Maybe that is not getting reset.

See Post #13 and Post #14.

1 Like

I was not enabling the watchdog. So that cannot be an issue. In any case, setting the value to 2048 works now. I will see after some of the application is finished what the stack use is for the task created and adjust accordingly. I do that for my MBed Portenta program, and leave about 100% minimum headroom (not too starved in RAM, so can be a little generous).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.