Error: assert failed: xQueueSemaphoreTake on ESP32 with SPIFFS

Hi, I and my team are making a library to use LoRa in an IoT project. The project involves several measuring devices sending Strings (it contains a json with data) to a master device (named bridge), in the tests we use the Heltec WiFi LoRa 32 (V2) board. When the bridge receives a message it may, sporadically, print an error message on the serial. This occurs at some point in the process, we do not identify an exact point or a specific frequency for the error to occur.

Code:

/*
  a simple bridge code using the default config:
  (timeout = 500 ms / txPower = 20 dBm / PaBoost = false / frequência = 915 MHz)
*/

#include <UnifyBridge.h> //Include the library
#include "env.h" //include a file with the WiFi SSID and password and also the HTTP server url (for testing only)
#include <SPIFFS.h>
#include <FS.h>

int httpCode;
const uint8_t localAddress = 1; //address of this device
UnifyBridge bridge(localAddress); //declares the UnifyBridge class object


//SPIFFS functions:
int listDir() {  //return number of files
  File root = SPIFFS.open("/");
  if (!root) { return -1; }  //Open the "directory" where the files are in SPIFFS and check if there is a failure, if so it returns -1.

  File file = root.openNextFile();  //Reports the next file in the "directory" and passes the return to the File type variable.
  int qtdFiles = 0;                 //variable that stores the number of files in the specified directory.
  while (file) {                    //As long as there are files in the "directory" that have not been seen, execute the while loop.
    qtdFiles++;
    file = root.openNextFile();
  }
  file.close(); // close the last file
  return qtdFiles;
}

String readFile(String path) {
  String content;
  File file = SPIFFS.open(path); //Opens the SPIFFS file path and passes the return to a variable of type File.
  if (!file) return "";         //If there is a failure to open the path, it returns an empty String.
  while (file.available()){ //As long as there are any bytes available for reading the file, it executes the reading.
    char caractere = file.read();
    content += caractere;
  }  
  file.close();
  return content; // return the content
}

bool writeFile(String path, String message) {
  File file = SPIFFS.open(path, FILE_WRITE);  //Opens the file in writing mode and passes the return to a variable of type File.

  if (!file) { return false; }                 //If there is a failure to open the path, it returns false
  if (!file.print(message)) { return false; }  //If writing the file with its content gives an error, it returns false

  file.close();
  return true;
}

bool deleteFile(String path) {
  if (SPIFFS.remove(path)) { return true; }  //deletes the file passing the path/name (path). If the deletion is successful, returns true
  return false;                              //if there is an error, return false
}

void setup() {
  Serial.begin(115200);
  Serial.println("Starting bridge…");
  bridge.begin(BRIDGE, SSID, password); //start the bridge
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.print("connected to the network: ");
  Serial.println(SSID);
  Serial.println("setting server...");
  bridge.addServer(serverN);
  Serial.println("entrando em void loop...");
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);

  SPIFFS.begin(); //start SPIFFS
}

void loop() {
  String json; //String that will store received json.
  //wait a message
  if(bridge.receiveLoRa()){
    digitalWrite(LED_BUILTIN, HIGH);
    json = bridge.getMessage();
    Serial.println("message: " + json); //print the message on the serial monitor
    Serial.print("RSSI: " + String(bridge.getRSSI())); //print RSSI on the serial monitor
    Serial.print("| Json error: " + bridge.getError() + " | "); //print message json error on serial monitor
    bridge.sendResponse(bridge.montarJson()); //responds to a message reporting an error in a json assembled for this type of communication
    
    
    if(bridge.getError() == "Ok"){
      //checks if the json is intact
      Serial.println("Json is intact");
      
      if(bridge.isConnected()){
        httpCode = bridge.postHTTP(json);
        // HTTP header has been send and Server response header has been handled
        Serial.print("[HTTP] POST code: ");
        Serial.println(httpCode);
      }else{
        Serial.println("WiFi is not connected");
        String dir = "/data/" + String(listDir() + 1) + ".txt"; //creates file based on the number of files in the directory in ascending order
        Serial.println("Store data in: " + dir);
        writeFile(dir, json);
      }

    }else{
      Serial.println("Json is not intact");
    }
  }else if(bridge.isConnected() && listDir() > 0){//check wifi and file usage on SPIFFS
    String dir = "/data/" + String(listDir()) + ".txt";
    String Content = readFile(dir);
    Serial.println("Posting content from: " + dir);
    httpCode = bridge.postHTTP(Content);
    // HTTP header has been send and Server response header has been handled
    Serial.print("[HTTP] POST code: ");
    Serial.println(httpCode);
    if(httpCode > 199 && httpCode < 300){
      deleteFile(dir);
    }
  }

  //reading the serial to access SPIFFS
  if(Serial.available() > 0){
    char incomingByte = Serial.read();
    switch (incomingByte){
      case 'p': //lowercase p to print all files
          for(int i = listDir(); i > 0; i--){
            String dir = "/data/" + String(i) + ".txt";
            String Content = readFile(dir);
            Serial.println("============================================================================================");
            Serial.println();
            Serial.print("Content from : ");
            Serial.println(dir);
            Serial.println(Content);
            Serial.println();
          }
        break;
      case 'd': //lowercase d to delete all files
        for(int i = listDir(); i > 0; i--){               //if there is, send it in a loop until there is none left
          String dir = "/data/" + String(i) + ".txt";
          if(deleteFile(dir)){
            Serial.print(dir);
            Serial.println("was deleted");
          }else{
            Serial.print(dir);
            Serial.println("was not deleted because of an error");
          }
        }
        break;
      case 'f': //lowercase f to format
        Serial.println("formatting SPIFFS...");
        SPIFFS.format();
        Serial.println("SPIFFS Formated!");
        break;
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
  delay(10);
}

Error:

assert failed: xQueueSemaphoreTake queue.c:1554 (!( ( xTaskGetSchedulerState() == ( ( BaseType_t ) 0 ) ) && ( xTicksToWait != 0 ) ))

Backtrace: 0x4008383d:0x3ffbf27c |<-CORRUPTED

ELF file SHA256: 61b4cca081570768

After the error the board restarts automatically. UnifyBridge contains the libraries RH_RF95 e RHmesh (part of Radiohead library), WiFi.h, ArduinoJson, HTTPclient and SPI.

The error appears to be related to an assertion failure during code execution. The message indicates that the failure occurred in the xQueueSemaphoreTake function in the queue.c file, line 1554, a FreeRTOS component. The failed assertion is checking some conditions related to the state of the task scheduler and the waiting time. It appears that the assertion is being violated, which may indicate an unexpected condition in the program's execution flow.

When trying to locate the queue.c file in the Arduino IDE folders we were unable to find it, only similar ones with the .h extension or no extension. And these files do not have the long-awaited line 1554, when it exists it does not have the xQueueSemaphoreTake function.

When trying to locate the queue.c file in the Arduino IDE folders we were unable to find it, only similar ones with the .h extension or no extension. And these files do not have the long-awaited line 1554, when it exists it does not have the xQueueSemaphoreTake function.

When doing a test on another example without using SPIFFS (last functionality to be added) I don't get the same error, I can't simply remove SPIFFS as it is a fundamental part of the project since we are avoiding the use of SD card modules . This error compromises the functioning of the device and our development as there are more features to be included in our device, all of which are strictly necessary.

We need help with this, we don't have much idea what to do

Hi @Bracinho_3535 ,

Welcome to the forum..

Been looking at this, backtrace all corrupted, not good..
Means you can't trace back to source line..
Something blowing out..

one thing sticks out..
second "if"
file.print could fail if not enough room leaving a file handle open, few of these and good night..
add a file.close(); before returning false..

if (still blowing up)
how long does it run for??
what is last few serial prints before crash??

good luck.. ~q

Hi @qubits-us , thank you for the support

Unfortunately your suggestion doesn't solve the problem, I add file.close(); in this part and other parts of the code that I thought necessary

//SPIFFS functions:
int listDir() {  //return number of files
  File root = SPIFFS.open("/");
  if (!root) { 
    root.close();
    return -1; 
  }  //Open the "directory" where the files are in SPIFFS and check if there is a failure, if so it returns -1.

  File file = root.openNextFile();  //Reports the next file in the "directory" and passes the return to the File type variable.
  int qtdFiles = 0;                 //variable that stores the number of files in the specified directory.
  while (file) {                    //As long as there are files in the "directory" that have not been seen, execute the while loop.
    qtdFiles++;
    file = root.openNextFile();
  }
  file.close(); // close the last file
  return qtdFiles;
}

String readFile(String path) {
  String content;
  File file = SPIFFS.open(path); //Opens the SPIFFS file path and passes the return to a variable of type File.
  if (!file) {
    file.close();
    return "";//If there is a failure to open the path, it returns an empty String.
  }         
  while (file.available()){//As long as there are any bytes available for reading the file, it executes the reading.
    char caractere = file.read();
    content += caractere;
  }  
  file.close(); 
  return content; // return the content
}

bool writeFile(String path, String message) {
  File file = SPIFFS.open(path, FILE_WRITE);  //Opens the file in writing mode and passes the return to a variable of type File.

  if (!file) {
    //If there is a failure to open the path, it returns false
    file.close();
    return false;
  }                 
  if (!file.print(message)) { 
    //If writing the file with its content gives an error, it returns false
    file.close();
    return false;
  } 

  file.close();
  return true;
}

The device stays working for some time, and receive some messages, send the response to original sender and post the content via http or stores the content in SPIFFS (a few seconds later make another post). After this the esp may or may not crash and restart, it usually fails after receiving between one and three messages, it is very unstable.

The last serial prints is:

  1. if don't use SPIFFS:

message: {"timestamp":"datetime","type":"power","measures":{"device":{"tag":"PG:7C:9E:BD:5A:EA:28"},"values":{"generation":0,"demand":[0,0,0,0],"powerFactor":0}}}
RSSI: -48| Json error: Ok | Json is intact
[HTTP] POST code: 204

  1. if do use SPIFFS:

message: {"timestamp":"datetime","type":"power","measures":{"device":{"tag":"PG:7C:9E:BD:5A:EA:28"},"values":{"generation":2,"demand":[2,2,2,2],"powerFactor":2}}}
RSSI: -49| Json error: Ok | Json is intact
WiFi is not connected
Store data in: /data/1.txt
Posting content from: /data/1.txt
[HTTP] POST code: 204

EDIT: The error also occurs in some attempts to format SPIFFS via Serial (third if block with switch case inside).

looking some more..

the Strings dir and Content get re-declared a few times inside the loop..
declare them at the top and remove the other declarations..

some of their declarations are inside 2 of the case statements for serial processing..

declaring local vars inside of cases is frowned upon, probably breaking your cases, typically causes the case to ignore it's break and flow down to next case, enclosing the offending case inside {} typically corrects this behavior..

curious how often does the processing happen (receiving Lora and posting)??

Backtrace always corrupted??

~q

Got a link for this lib, can't seem to locate it??

Also curious about memory usage..
add this line..

 Serial.printf("Free Heap: %d \n",xPortGetFreeHeapSize());

just after you recv from Lora..

~q

declare the string dir and Content once in void loop become the problem less frequent, but still persists. I add Serial.printf("Free Heap: %d \n",xPortGetFreeHeapSize()); to code and ran for a hour, these are the pre-failure serial prints:

Free Heap: 161656
Mensagem: {"timestamp":"datetime","type":"power","measures":{"device":{"tag":"PG:7C:9E:BD:5A:EA:28"},"values":{"generation":6,"demand":[6,6,6,6],"powerFactor":6}}}
RSSI: -55| Erro do json: Ok |

Free Heap: 161512
menssage: {"timestamp":"datetime","type":"power","measures":{"device":{"tag":"PG:7C:9E:BD:5A:EA:28"},"values":{"generation":35,"demand":[35,35,35,35],"powerFactor":35}}}
RSSI: -55| Json error: Ok | Json is intact
WiFi is not connected
Store data in: /data/35.txt

Code:

void loop() {
  String json, dir, Content; //String that will store received json.
  //wait a message
  if(bridge.receiveLoRa()){
    Serial.printf("Free Heap: %d \n",xPortGetFreeHeapSize());

The error also happened when I try format the SPIFFS, this is not urgent, but it is worrying.

A new error happened when I accidentally touched the board bottom. I think my touch somehow caused the error, but it could be a coincidence. see the error below:

�Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x400908d120966 130c3007 8900e282
Core 0 register dump:
�a $����
��� PS : 0x00060033 A0 �008f1e3 A1 : 0x3ffbec9c
A2 : 0xs� �����G���‰�3fffff A4 : 0x0000aba����0060023
A6 : 0x00060021 A7�0$������ A8 : 0x0000cdcd A9 ��������
A10 : 0x3ffc4d0 A11 �8��&2��c A13 ���j
A14 : 0x007bf578 �j���хѥ���Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.

Core 0 register du���PC : 0x40089ce4 PS : 0x00060534 A0 : 0x800efadf A1 : 0x3ffbe98c
A2 : 0x00000040 A3 : 0x00000000 A4 : 0x00000004 A5 : 0x0000x��������0000000 A7 : 0x00000000 A8 : 0x800e7cfa A9 : 0x3ffbeafc
A10 : 0x3ffbeb78 A11 : 0x3ffbdcfc A12 : 0x3f403737 A13 : 0x400e7d60
A14 : 0x000249f0 A15 : 0x00000002 SAR : 0x0000000a EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000040 LBEG : 0x40089ccc LEND : 0x40089cd7 LCOUNT : 0xffffffff

Backtrace: 0x40089ce1:0x3ffbe98c |<-CORRUPTED

ELF file SHA256: 8bcc63d19b73e8f5

Rebooting...

every 10 seconds a message is send to bridge, and the sender device try three times if no recive the response (it waits 5 seconds for resending). The post via http usually takes between 1 to 2 seconds.

Yes, the message error is the same most of the time, so I believe so

Sorry, but our lib is private. By now, that development have the purpose of accelerate other product developments using LoRa. So, I can't share so much internal details and, especially, the source code, at least for now.

guess that's why i couldn't find it.. :slight_smile:

memory fragmentation leading to corruption..
remove use of the String class as much as possible..
best if you could remove them all..

sorry.. ~q

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