Page 1 of 1

Mutex test program crashes the ESP32

Posted: Wed Feb 12, 2025 1:07 pm
by Mark-Robert
Hello.

I have written a program to test my understanding of FreeRTOS mutext behaviour, but I'm having a problem. When running the following code, I have two observations:
  • The code randomly crashes, causing the ESP32 to reboot
  • The frequency of change from display AAAAAAAAA to BBBBBBBBBB is much lower than I was expecting, implying that the tasks are swapping very very slowly.
Here is the code. The intention of the code is protect 'str' such that one only sees AAAAAAAAAA or BBBBBBBBBB. This works, but very slowly (many lines of AAAA.... and BBBB... are displayed - they do not change state very often), and why does the machine crash?

If anyone could provide some insight I'd be very grateful. I'm using the Arduino platform via PlatformIO.

Many thanks

Code: Select all

#include <Arduino.h>

SemaphoreHandle_t myMutex = NULL;

char str[] = "0123456789";

void taskA(void *pvParameters)
{
  while (1)
  {
    if (xSemaphoreTake(myMutex, pdMS_TO_TICKS(1000)) == pdTRUE)
    {
      for (auto i = 0; i < 10; i++)
        str[i] = 'a';

      xSemaphoreGive(myMutex);
    }
    else
      vTaskDelay(pdMS_TO_TICKS(20));
  }
}

void taskB(void *pvParameters)
{
  while (1)
  {
    if (xSemaphoreTake(myMutex, pdMS_TO_TICKS(1000)) == pdTRUE)
    {
      for (auto i = 0; i < 10; i++)
        str[i] = 'b';

      xSemaphoreGive(myMutex);
    }
    else
      vTaskDelay(pdMS_TO_TICKS(20));
  }
}

void setup()
{
  Serial.begin(9600);

  while (!Serial)
    ;
  myMutex = xSemaphoreCreateMutex();

  xTaskCreate(
      taskA,     /* Function that implements the task. */
      "tA",      /* Text name for the task. */
      2048,      /* Stack size in words, not bytes. */
      (void *)1, /* Parameter passed into the task. */
      1,         /* Priority at which the task is created. */
      NULL);     /* Used to pass out the created task's handle. */

  xTaskCreate(
      taskB,     /* Function that implements the task. */
      "tB",      /* Text name for the task. */
      2048,      /* Stack size in words, not bytes. */
      (void *)1, /* Parameter passed into the task. */
      1,         /* Priority at which the task is created. */
      NULL);     /* Used to pass out the created task's handle. */
}

void loop()
{
  Serial.println(str);
}

Re: Mutex test program crashes the ESP32

Posted: Thu Feb 13, 2025 2:08 am
by ESP_Sprite
No clue why the crash is; it may be because you don't have anything blocking in your loop() block. I'm decently sure your code works, but what likely happens is that between Serial.println() statements, both tasks get to run a lot of time, and the timing just happens to be such that the task who gets to run last happens to be the same a lot of time. I'm actually surprised you don't get the odd 'AAAABBBB' in there either, as you didn't protect your Serial.println() and as such it could theoretically run while one of the tasks is in the process of overwriting the string. Guess you also just got lucky wrt timing.

Re: Mutex test program crashes the ESP32

Posted: Thu Feb 13, 2025 12:36 pm
by Mark-Robert
Hi

Examining the error output closely, it says that Task IDLE0 (IIRC) didn't service the watchdog quick enough. I fixed that with a vTaskDelay in loop().

Many thanks
Mark-Robert

Re: Mutex test program crashes the ESP32

Posted: Thu Feb 13, 2025 12:43 pm
by chegewara
1. add long delay in loop, so this task not mess with your mutex tests
2. add in "mutex" tasks vPortYield(); or some very small delay, because now the tasks dont have chance to switch; this also may be the cause of crash (WDT)