Guru meditation errors

Hi!

I use Arduino IDE to program my ESP32. Sometimes I get some errors from Guru Meditation, like this:

Guru Meditation Error of type StoreProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x400f360d  PS      : 0x00060330  A0      : 0x800dbf56  A1      : 0x3ffb7e00
A2      : 0x3ffb136c  A3      : 0x00000005  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000080  A8      : 0x00000000  A9      : 0x3ffb7dd0
A10     : 0x00000003  A11     : 0x00060f23  A12     : 0x00060f20  A13     : 0x3ffba6d0
A14     : 0x00000047  A15     : 0x0000000f  SAR     : 0x00000019  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90

I see on the internet that people can identify where the error occurred using the backtrace:

Guru Meditation Error of type StoreProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x400f360d  PS      : 0x00060330  A0      : 0x800dbf56  A1      : 0x3ffb7e00
0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57
(inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52
A2      : 0x3ffb136c  A3      : 0x00000005  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000080  A8      : 0x00000000  A9      : 0x3ffb7dd0
A10     : 0x00000003  A11     : 0x00060f23  A12     : 0x00060f20  A13     : 0x3ffba6d0
A14     : 0x00000047  A15     : 0x0000000f  SAR     : 0x00000019  EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000000

Backtrace: 0x400f360d:0x3ffb7e00 0x400dbf56:0x3ffb7e20 0x400dbf5e:0x3ffb7e40 0x400dbf82:0x3ffb7e60 0x400d071d:0x3ffb7e90
0x400f360d: do_something_to_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:57
(inlined by) inner_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:52
0x400dbf56: still_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:47
0x400dbf5e: dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:42
0x400dbf82: app_main at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:33
0x400d071d: main_task at /home/gus/esp/32/idf/components/esp32/./cpu_start.c:254

How to do this?
I tried to find it but couldn't, does anyone know?

Thanks!

have a look at

Trying to run IDF code in the Arduino IDE?

Post the code giving the error.

@filipekerplunk, your topic has been moved to a more suitable location on the forum.

Varnish Cache issues the Guru Meditation error when a connection has timed out or the Varnish Cache server has made too many requests to the back end server without getting a response.

MyCCPay

This type of exception depends of your code.
Probably you are trying to access an invalid memory location.

Looking at the sketch can be useful to find the issue.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/fatal-errors.html#loadprohibited-storeprohibited

Thank you all!

I installed the ESP Exception Decoder and put the error there, but apparently it's not a code-specific or library-specific error:

I get this error sometimes when I get a mqtt message a little big (21000 bytes). Even though the mqtt buffer is 30000 bytes in the code. It's not an error that happens all the time, so I think it's RAM overflow, is that possible?

Is the buffer a global variable or on the stack?

What error? All I see is decoding stack results. WHy not highlight the decoded message, contrtl c to copy it and paste the text here?

You may have to inquire with your MQTT Broker as to their set max payload size. The default max payload size is 256MB.

I think it's better if you put here your code.
Othrrway it is very hard for us trying to help you.

Varnish Cache issues the Guru Meditation error when a connection has timed out or the Varnish Cache server has made too many requests to the back end server without getting a response.

Hi!

Here is my code, it only receives messages from mqtt in JSON so I can create a class.

class Locker
{
  public:
    String id;
    String status;
    String dataStatus;
    int number;
    String document;
    String keycode;
    String bookingNumber;
    String nrOfDays;
};

Locker lockers[99];

void callback(char* topic,  unsigned char* message, unsigned int length) {
  dbSerialPrint("Mensagem chegou no topico: ");
  dbSerialPrint(topic);
  dbSerialPrint(". Tamanho: ");
  dbSerialPrint(length);

  String messageTemp;
  //json = "";
  for (int i = 0; i < length; i++) {
    //dbSerialPrint((char)message[i]);
    messageTemp += (char)message[i];
  }
  criarClasse(messageTemp); //desserialize
  gravarArquivo(messageTemp); //write in spiffs
  messageTemp = "";
}


void criarClasse(String json)
{


  DynamicJsonDocument doc(30000);

  DeserializationError error = deserializeJson(doc, json);

  if (error) {
    dbSerialPrint(F("deserializeJson() failed: "));
    dbSerialPrintln(error.f_str());
  }

  JsonObject root = doc.as<JsonObject>();
 
  int count = -1;
  for (JsonPair kv : root)
  {
    count++;
    lockers[count].id = kv.key().c_str();
    lockers[count].document = (const char*)doc[lockers[count].id]["document"];
    lockers[count].keycode = (const char*)doc[lockers[count].id]["keycode"];
    lockers[count].number = doc[lockers[count].id]["number"];
    lockers[count].status = (const char*)doc[lockers[count].id]["status"];
    lockers[count].nrOfDays = (const char*)doc[lockers[count].id]["nrOfDays"];
    lockers[count].bookingNumber = (const char*)doc[lockers[count].id]["bookingNumber"];
    lockers[count].dataStatus = (const char*)doc[lockers[count].id]["dataStatus"];
  }

void gravarArquivo(String gravar)
{
  //Write SPIFFS
  File f = SPIFFS.open("/myspiffs.json", "w");
  f.print(gravar);
  f.close();
}

In some of those moments, when receiving the mqtt, he gives this Guru Meditation error. Not always, in some random moments.

Guru Meditation Error: Core 1 panic'ed (LoadStoreError). Exception was unhandled.
Core 1 register dump:
PC : 0x400dd76a PS : 0x00060a30 A0 : 0x801664c6 A1 : 0x3ffb1e90
A2 : 0x3ffc72e8 A3 : 0x40000000 A4 : 0x3ffd3414 A5 : 0x3ffc7120
A6 : 0x3f401a52 A7 : 0x3ffc72e8 A8 : 0x800dd775 A9 : 0x3ffb1e60
A10 : 0x00000000 A11 : 0x00000000 A12 : 0x80089520 A13 : 0x3ffb1dc0
A14 : 0x00000000 A15 : 0x3ffb0060 SAR : 0x00000010 EXCCAUSE: 0x00000003
EXCVADDR: 0x40000000 LBEG : 0x4000c28c LEND : 0x4000c296 LCOUNT : 0x00000000
Backtrace: 0x400dd76a:0x3ffb1e90 0x401664c3:0x3ffb1ee0 0x400e0a67:0x3ffb1f00 0x400dee9e:0x3ffb1f40 0x400ec4e1:0x3ffb1fb0 0x4008930d:0x3ffb1fd0
Rebooting...

Putting the error in the decoder, nothing else is displayed:

What is Varnish Cache?

It's incomplete. Any reason you can't post the full code?

Regardless, I’ll take a stab at it. I’m guessing that your cavalier attitude towards stack space is blowing up the memory allocated for the task in which callback() is running.

Alternately, if callback() is running in interrupt context (I really don’t know, since your code is incomplete and the MQTT library is not evident), then you’re doing a an awful lot of stuff in an ISR.

A callback for a ESP32 that works

void IRAM_ATTR mqttCallback(char* topic, byte * payload, unsigned int length)
{
  // clear locations
  memset( x_message.payload, '\0', payloadSize );
  x_message.topic = ""; //clear string buffer
  x_message.topic = topic;
  int i = 0;
  for ( i; i < length; i++)
  {
    x_message.payload[i] = ((char)payload[i]);
  }
  x_message.payload[i] = '\0';
  xQueueOverwrite( xQ_Message, (void *) &x_message );// send data to queue
} // void mqttCallback(char* topic, byte* payload, unsigned int length)

Notice the differences between OP's callback and one that works?

It would probably be helpful to see the definition of 'x_message'.

The definition of x_message and other things.

#include "sdkconfig.h" // used for log printing
#include "esp_system.h"
#include "freertos/FreeRTOS.h" //freeRTOS items to be used
#include "freertos/task.h"
#include "certs.h"
#include "esp_camera.h"
#include "soc/soc.h"           // Disable brownout problems
#include "soc/rtc_cntl_reg.h"  // Disable brownout problems
#include "driver/rtc_io.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include "ESP32_FTPClient.h"
#include <PubSubClient.h>
#include <ESP32Time.h>
//
WiFiClient      wifiClient; // do the WiFi instantiation thing
PubSubClient    MQTTclient( mqtt_server, mqtt_port, wifiClient ); //do the MQTT instantiation thing
ESP32_FTPClient ftp (ftp_server, ftp_user, ftp_pass, 5000, 2);
ESP32Time       rtc;
////
//#define evtDoMQTTParse  ( 1 << 0 ) // declare an event
//EventGroupHandle_t eg; // variable for the event group handle
////
SemaphoreHandle_t sema_MQTT_KeepAlive;
SemaphoreHandle_t sema_mqttOK;
////
QueueHandle_t xQ_Message; // payload and topic queue of MQTT payload and topic
const int payloadSize = 300;
struct stu_message
{
  char payload [payloadSize] = {'\0'};
  String topic ;
} x_message;
////
int  mqttOK = 0;
bool TimeSet = false;
bool FlashMode = false;
//
void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      log_i("Connected to WiFi access point");
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      log_i("Disconnected from WiFi access point");
      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      log_i("WiFi client disconnected");
      break;
    default: break;
  }
} // void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
//
void IRAM_ATTR mqttCallback(char* topic, byte * payload, unsigned int length)
{
  // clear locations
  memset( x_message.payload, '\0', payloadSize );
  x_message.topic = ""; //clear string buffer
  x_message.topic = topic;
  int i = 0;
  for ( i; i < length; i++)
  {
    x_message.payload[i] = ((char)payload[i]);
  }
  x_message.payload[i] = '\0';
  xQueueOverwrite( xQ_Message, (void *) &x_message );// send data to queue
} // void mqttCallback(char* topic, byte* payload, unsigned int length)
////
void setup()
{
  pinMode( GPIO_NUM_4, OUTPUT);
  digitalWrite( GPIO_NUM_4, LOW);
  //
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
  //
  //eg = xEventGroupCreate(); // get an event group handle
  //
  x_message.topic.reserve( payloadSize );
  //
  xQ_Message  = xQueueCreate( 1, sizeof(stu_message) );
  //
  sema_mqttOK    =  xSemaphoreCreateBinary();
  xSemaphoreGive( sema_mqttOK );
  //
  xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 7000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fparseMQTT, "fparseMQTT", 9000, NULL, 4, NULL, 1 ); // assign all to core 1, WiFi in use.
  xTaskCreatePinnedToCore( fmqttWatchDog, "fmqttWatchDog", 3000, NULL, 2, NULL, 1 );
  if ( configInitCamera() )
  {
    log_i("        start camera task" );
    xTaskCreatePinnedToCore( capturePhoto_sendFTP, "capturePhoto_sendFTP", 60000, NULL, 6, NULL, 1 );
  } else {
    log_i( "       camera failed to initilize, rebooting in 5." );
    vTaskDelay( 2000 );
    ESP.restart();
  }
} // void setup()
////
void capturePhoto_sendFTP( void *pvParameters )
{
  TickType_t xLastWakeTime    = xTaskGetTickCount();
  const TickType_t xFrequency = 1000 * 15; //delay for mS
  //!!!!!Must wait for MQTT connection and proper setup of the sema_MQTT_KeepAlive!!!!
  while ( !MQTTclient.connected() )
  {
    vTaskDelay( 500 );
  }
  for (;;)
  {
    log_i( "tick");
    xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      camera_fb_t * fb = NULL; // pointer
      if( FlashMode )
      {
        digitalWrite( GPIO_NUM_4, HIGH );
        vTaskDelay( 20 );
      }
      fb = esp_camera_fb_get();
      digitalWrite( GPIO_NUM_4, LOW );
      if (!fb)
      {
        log_i( "Camera capture failed" );
        esp_camera_fb_return(fb);
      } else
      {
        ftp.OpenConnection(); // try open FTP
        if ( ftp.isConnected() )
        {
          //try send file ftp
          ftp.ChangeWorkDir( ftp_path );
          ftp.DeleteFile( ftp_file_name );
          ftp.InitFile( ftp_file_type ); //"Type I"
          ftp.NewFile( ftp_file_name );
          ftp.WriteData( (unsigned char *)fb->buf, fb->len );
          ftp.CloseFile();
          ftp.CloseConnection();
        }
        esp_camera_fb_return(fb); //return the frame buffer back to the driver for reuse
      }
    }
    xSemaphoreGive( sema_MQTT_KeepAlive );
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete( NULL );
} //void capturePhoto_sendFTP( void *pvParameters )
////
void configureCameraSettings_grpE( int _lenC, int _Hmirror, int _Vflip, int _dcw, int _colorbar )
{
  sensor_t * s = esp_camera_sensor_get();
  s->set_lenc(s, _lenC);         // 0 = disable , 1 = enable
  s->set_hmirror(s, _Hmirror);   // 0 = disable , 1 = enable
  s->set_vflip(s, _Vflip);       // 0 = disable , 1 = enable
  s->set_dcw(s, _dcw);           // 0 = disable , 1 = enable
  ////s->set_colorbar(s, _colorbar); // 0 = disable , 1 = enable
}
////
void configureCameraSettings_grpD( int _gc, int _agc, int _celing, int _bpc, int _wpc, int _gma )
{
  sensor_t * s = esp_camera_sensor_get();
  s->set_gain_ctrl(s, _gc); // 0 = disable , 1 = enable
  s->set_agc_gain(s, _agc); // 0 to 30
  s->set_gainceiling(s, (gainceiling_t)_celing);  // 0 to 6
  s->set_bpc(s, _bpc);      // 0 = disable , 1 = enable
  s->set_wpc(s, _wpc);      // 0 = disable , 1 = enable
  s->set_raw_gma(s, _gma);  // 0 = disable , 1 = enable
}
////
void configureCameraSettings_grpC( int _exctl, int _aec2, int _ae, int _aec )
{
  sensor_t * s = esp_camera_sensor_get();
  s->set_exposure_ctrl(s, _exctl); // 0 = disable , 1 = enable
  s->set_aec2(s, _aec2);           // 0 = disable , 1 = enable
  s->set_ae_level(s, _ae);         // -2 to 2
  ////s->set_aec_value(s, _aec);       // 0 to 1200 CAUSES BLACK IMAGE????
}
////
void configureCameraSettings_grpB( int se, int wb, int awb, int wbmode )
{
  sensor_t * s = esp_camera_sensor_get();
  s->set_special_effect(s, se); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
  s->set_whitebal(s, wb);       // 0 = disable , 1 = enable
  s->set_awb_gain(s, awb);      // 0 = disable , 1 = enable
  s->set_wb_mode(s, wbmode);    // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
}
////
void configureCameraSettings_grpA(int brightness, int contrast, int saturation )
{
  if ( ((brightness > -3) && (brightness < 3)) && ((contrast > -3) && (contrast < 3)) && ((saturation > -3) && (saturation < 3)) )
  {
    sensor_t * s = esp_camera_sensor_get();
    s->set_brightness( s, brightness ); // -2 to 2
    s->set_contrast( s, contrast );    // -2 to 2
    s->set_saturation( s, saturation );  // -2 to 2
  }
} //void configureCameraSettings()
////
void configureCameraSettings()
{
  sensor_t * s = esp_camera_sensor_get(); //see certs.h for more info
  s->set_brightness(s, -1);     // -2 to 2 **************************
  s->set_contrast(s, 0);       // -2 to 2
  s->set_saturation(s, 0);     // -2 to 2
  s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
  s->set_whitebal(s, 1);       // 0 = disable , 1 = enable
  s->set_awb_gain(s, 1);       // 0 = disable , 1 = enable
  s->set_wb_mode(s, 0);        // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
  s->set_exposure_ctrl(s, 1);  // 0 = disable , 1 = enable
  s->set_aec2(s, 0);           // 0 = disable , 1 = enable
  s->set_ae_level(s, 0);       // -2 to 2
  s->set_aec_value(s, 300);    // 0 to 1200
  s->set_gain_ctrl(s, 1);      // 0 = disable , 1 = enable
  s->set_agc_gain(s, 0);       // 0 to 30
  s->set_gainceiling(s, (gainceiling_t)0);  // 0 to 6
  s->set_bpc(s, 0);            // 0 = disable , 1 = enable
  s->set_wpc(s, 1);            // 0 = disable , 1 = enable
  s->set_raw_gma(s, 1);        // 0 = disable , 1 = enable
  s->set_lenc(s, 1);           // 0 = disable , 1 = enable
  s->set_hmirror(s, 0);        // 0 = disable , 1 = enable
  s->set_vflip(s, 0);          // 0 = disable , 1 = enable
  s->set_dcw(s, 1);            // 0 = disable , 1 = enable
  s->set_colorbar(s, 0);       // 0 = disable , 1 = enable
} //void configureCameraSettings()
////
bool configInitCamera()
{
  camera_config_t config = {}; // Stores the camera configuration parameters
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer   = LEDC_TIMER_0;
  config.pin_d0       = GPIO_NUM_5; //Y2
  config.pin_d1       = GPIO_NUM_18; //Y3
  config.pin_d2       = GPIO_NUM_19; //Y4
  config.pin_d3       = GPIO_NUM_21; //Y5
  config.pin_d4       = GPIO_NUM_36; //Y6
  config.pin_d5       = GPIO_NUM_39; //Y7
  config.pin_d6       = GPIO_NUM_34; //Y8
  config.pin_d7       = GPIO_NUM_35; // Y9
  config.pin_xclk     = GPIO_NUM_0; //XCLK
  config.pin_pclk     = GPIO_NUM_22; //PCLK
  config.pin_vsync    = GPIO_NUM_25; //VSSYNC
  config.pin_href     = GPIO_NUM_23; // HREF
  config.pin_sscb_sda = GPIO_NUM_26; //SIOD
  config.pin_sscb_scl = GPIO_NUM_27; //SIOC
  config.pin_pwdn     = GPIO_NUM_32; //PWDN
  config.pin_reset    = -1; //RESET
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; //assuming default is has PSRAM
  config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
  config.jpeg_quality = 10; //0-63 lower number means higher quality
  config.fb_count = 2;
  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    log_i("Camera init failed with error %d", err );
    return false;
  } else {
    configureCameraSettings();
    return true;
  }
} //void configInitCamera()
////
void connectToWiFi()
{
  int TryCount = 0;
  while ( WiFi.status() != WL_CONNECTED )
  {
    TryCount++;
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    vTaskDelay( 2500 );
    if ( TryCount == 10 )
    {
      ESP.restart();
    }
  }
  WiFi.onEvent( WiFiEvent );
}
////
void MQTTkeepalive( void *pvParameters )
{
  sema_MQTT_KeepAlive   = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
  MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 250; //delay for ms
  for (;;)
  {
    //check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // !!!!!whiles MQTTlient.loop() is running no other mqtt operations should be in process!!!!!
      MQTTclient.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
    }
    else {
      if ( !(wifiClient.connected()) || !(WiFi.status() == WL_CONNECTED) )
      {
        connectToWiFi();
      }
      connectToMQTT();
    }
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete ( NULL );
}
////
void connectToMQTT()
{
  byte mac[5]; // create client ID from mac address
  WiFi.macAddress(mac); // get mac address
  String clientID = String(mac[0]) + String(mac[4]) ; // use mac address to create clientID
  while ( !MQTTclient.connected() )
  {
    MQTTclient.connect( clientID.c_str(), mqtt_username, mqtt_password );
    vTaskDelay( 250 );
  }
  MQTTclient.setCallback( mqttCallback );
  MQTTclient.subscribe( topicOK );
  MQTTclient.subscribe( topicGrpA );
  MQTTclient.subscribe( topicGrpB );
  MQTTclient.subscribe( topicGrpC );
  MQTTclient.subscribe( topicGrpD );
  MQTTclient.subscribe( topicGrpE );
  MQTTclient.subscribe( topicFlash );
} //void connectToMQTT()
//////
void fmqttWatchDog( void * paramater )
{
  int UpdateImeTrigger = 86400; //seconds in a day
  int UpdateTimeInterval = 85000; // get another reading when = UpdateTimeTrigger
  int maxNonMQTTresponse = 3;
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 60000; //delay for mS
  for (;;)
  {
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    xSemaphoreTake( sema_mqttOK, portMAX_DELAY ); // update mqttOK
    mqttOK++;
    xSemaphoreGive( sema_mqttOK );
    if ( mqttOK >= maxNonMQTTresponse )
    {
      log_i( "mqtt watchdog rest" );
      vTaskDelay( 200 );
      ESP.restart();
    }
    UpdateTimeInterval++; // trigger new time get
    if ( UpdateTimeInterval >= UpdateImeTrigger )
    {
      TimeSet = false; // sets doneTime to false to get an updated time after a days count of seconds
      UpdateTimeInterval = 0;
    }
  }
  vTaskDelete( NULL );
} //void fmqttWatchDog( void * paramater )
////
void fparseMQTT( void *pvParameters )
{
  struct stu_message px_message;
  for (;;)
  {
    if ( xQueueReceive(xQ_Message, &px_message, portMAX_DELAY) == pdTRUE )
    {
      xSemaphoreTake( sema_mqttOK, portMAX_DELAY );
      mqttOK = 0;
      xSemaphoreGive( sema_mqttOK );
      if ( !TimeSet)
      {
        if ( String(px_message.topic) == topicOK )
        {
          String temp = "";
          temp        = px_message.payload[0];
          temp        += px_message.payload[1];
          temp        += px_message.payload[2];
          temp        += px_message.payload[3];
          int year    =  temp.toInt();
          temp        = "";
          temp        = px_message.payload[5];
          temp        += px_message.payload[6];
          int month   =  temp.toInt();
          temp        = "";
          temp        = px_message.payload[8];
          temp        += px_message.payload[9];
          int day     =  temp.toInt();
          temp        = "";
          temp        = px_message.payload[11];
          temp        += px_message.payload[12];
          int hour    =  temp.toInt();
          temp        = "";
          temp        = px_message.payload[14];
          temp        += px_message.payload[15];
          int min     =  temp.toInt();
          rtc.setTime( 0, min, hour, day, month, year );
          log_i( "%s   rtc  %s ", px_message.payload, rtc.getTime() );
          TimeSet     = true;
        }
      }
      if ( String(px_message.topic) == topicGrpA )
      {
        //finding first letter
        String sTmp = String( px_message.payload );
        int commaIndex = sTmp.indexOf(',');
        if ( sTmp.substring(0, commaIndex) == "a" );
        {
          int commaIndex = sTmp.indexOf(',');
          int brt =  (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int ctrast = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) ); // chop off begining of message
          int sat = (sTmp.substring(0, commaIndex)).toInt();
          configureCameraSettings_grpA( brt, ctrast, sat );
        }
      }
      if ( String(px_message.topic) == topicGrpB )
      {
        String sTmp = String( px_message.payload );
        int commaIndex = sTmp.indexOf(',');
        if ( sTmp.substring(0, commaIndex) == "b" );
        {
          int commaIndex = sTmp.indexOf(',');
          int se =  (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int wbb = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int wba = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int wbm = (sTmp.substring(0, commaIndex)).toInt();
          configureCameraSettings_grpB( se, wbb, wba, wbm );
        }
      }
      if ( String(px_message.topic) == topicGrpC )
      {
        String sTmp = String( px_message.payload );
        int commaIndex = sTmp.indexOf(',');
        if ( sTmp.substring(0, commaIndex) == "c" );
        {
          int commaIndex = sTmp.indexOf(',');
          int ex =  (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int aec2 = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int ae = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int aec = (sTmp.substring(0, commaIndex)).toInt();
          configureCameraSettings_grpC( ex, aec2, ae, aec );
        }
      }
      if ( String(px_message.topic) == topicGrpD )
      {
        String sTmp = String( px_message.payload );
        int commaIndex = sTmp.indexOf(',');
        if ( sTmp.substring(0, commaIndex) == "d" );
        {
          int commaIndex = sTmp.indexOf(',');
          int gc =  (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int agc = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int celing = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int bpc = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int wpc = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int gma = (sTmp.substring(0, commaIndex)).toInt();
          configureCameraSettings_grpD( gc, agc, celing, bpc, wpc, gma );
        }
      }
      if ( String(px_message.topic) == topicGrpE )
      {
        String sTmp = String( px_message.payload );
        int commaIndex = sTmp.indexOf(',');
        if ( sTmp.substring(0, commaIndex) == "e" );
        {
          int commaIndex = sTmp.indexOf(',');
          int lenC =  (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int Hmirror = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int Vflip = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int dcw = (sTmp.substring(0, commaIndex)).toInt();
          sTmp.remove( 0, (commaIndex + 1) );
          int colorbar = (sTmp.substring(0, commaIndex)).toInt();
          configureCameraSettings_grpE( lenC, Hmirror, Vflip, dcw, colorbar );
        }
      }
      if( String(px_message.topic) == topicFlash )
      {
        FlashMode = !FlashMode;
      }
    } //if ( xQueueReceive(xQ_Message, &px_message, portMAX_DELAY) == pdTRUE )
  } //for(;;)
  vTaskDelete( NULL );
} // void fparseMQTT( void *pvParameters )
////
void loop() {}

Sorry for not posting the full code, here it is:

#include <PubSubClient.h>
#include "ArduinoJson.h"
#include <SPIFFS.h>
#include <WiFiClient.h>
#include <ESP_WiFiManager.h>
#include <WiFi.h>
#include <Nextion.h>

const char* ssid = "ssidxxx";
const char* password = "passxxx";

String usuariomqtt = "esp32/usuario/xyz";
const char* mqtt_server = "xxx.xxx.xxx.xxx";
WiFiClient wifiClient;
PubSubClient client(wifiClient);

class Locker
{
  public:
    String id;
    String status;
    String dataStatus;
    int number;
    String document;
    String keycode;
    String bookingNumber;
    String nrOfDays;
};

Locker lockers[99];

void callback(char* topic,  unsigned char* message, unsigned int length) {
  dbSerialPrint("Mensagem chegou no topico: ");
  dbSerialPrint(topic);
  dbSerialPrint(". Tamanho: ");
  dbSerialPrint(length);

  String messageTemp;
  //json = "";
  for (int i = 0; i < length; i++) {
    //dbSerialPrint((char)message[i]);
    messageTemp += (char)message[i];
  }
  criarClasse(messageTemp); //desserialize
  gravarArquivo(messageTemp); //write in spiffs
  messageTemp = "";
}

void gravarArquivo(String gravar)
{
  //Write SPIFFS
  File f = SPIFFS.open("/myspiffs.json", "w");
  f.print(gravar);
  f.close();
}

void criarClasse(String json)
{


  DynamicJsonDocument doc(30000);

  DeserializationError error = deserializeJson(doc, json);

  if (error) {
    dbSerialPrint(F("deserializeJson() failed: "));
    dbSerialPrintln(error.f_str());
  }

  JsonObject root = doc.as<JsonObject>();
 
  int count = -1;
  for (JsonPair kv : root)
  {
    count++;
    lockers[count].id = kv.key().c_str();
    lockers[count].document = (const char*)doc[lockers[count].id]["document"];
    lockers[count].keycode = (const char*)doc[lockers[count].id]["keycode"];
    lockers[count].number = doc[lockers[count].id]["number"];
    lockers[count].status = (const char*)doc[lockers[count].id]["status"];
    lockers[count].nrOfDays = (const char*)doc[lockers[count].id]["nrOfDays"];
    lockers[count].bookingNumber = (const char*)doc[lockers[count].id]["bookingNumber"];
    lockers[count].dataStatus = (const char*)doc[lockers[count].id]["dataStatus"];
  }

}

void setup() {
  Serial.begin(9600);
  nexInit(115200);
  if (!SPIFFS.begin()) {
    SPIFFS.format();
    SPIFFS.begin();
  }
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi conectado");
  client.setServer(mqtt_server, 1883);
  client.setBufferSize(30000);
  client.setCallback(callback);
  client.setKeepAlive(90);

}

void loop() {
  verificaMqtt();
  client.loop();

}

void verificaMqtt()
{
  if (!client.connected())
  {
    dbSerialPrintln("DESCONECTOU MQTT, CONECTANDO NOVAMENTE");
    connectMqtt();
  }
}

void connectMqtt() {
  if (client.connect(usuariomqtt.c_str(), "user", "pass#1234")) {
    String sub = "firestore/teste/xxx";
    if (client.subscribe(sub.c_str())) {
      dbSerialPrintln("Se inscreveu no tópico");
      dbSerialPrintln(sub);
    }
    dbSerialPrintln("Erro ao inscrever no tópico");
  } else {
    dbSerialPrint("falha, erro =");
    dbSerialPrint(client.state());
  }
}

I'd still start by pulling on the threads I mentioned in Reply #16.

Also, @Idahowalker posted an example of a much leaner callback function. The use of the IRAM_ATTR designation suggests that the callback could happen in interrupt context or at least is time-critical.

Using FreeRTOS's (always running on ESP32) multi-tasking capability offers a lot of advantages.