espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.33k stars 7.36k forks source link

Stack smashing protect failure (using the BLE library) #3856

Closed jaggil closed 4 years ago

jaggil commented 4 years ago

Hardware:

Board: ESP32 Dev Module Core Installation version: esp32-1.0.4 BLE lib : Included in the Arduino ESP32 core 1.0.4 IDE name: Arduino IDE Flash Frequency: 40Mhz PSRAM enabled: no Upload Speed: 115200 Computer OS: Windows 10

Description:

My program aims to test the Xiaomi-Mijia-LYWSD03MMC humidity and temperature sensor. This device can only be read through notifications. To try to save battery, I want to turn notifications on and off from time to time, for example every minute, but keeping the BLE connection with the device. The program basically works, but every so often and randomly, the error "Stack smashing protect failure!" Occurs. I have done several tests and introduced some modifications after reading many posts, but there have been no results. There is always a sequence when the error occurs, which is that the "Notifications turned on" command stops appearing on the serial port, and after receiving four reads / notifications the error occurs and the ESP32 automatically restarts.

Other tests carried out are the following: 1.- Cancel the on / off commands of the loop (), canceling the two programming lines // pRemoteCharacteristic_THB-> getDescriptor (BLEUUID ((uint16_t) 0x2902)) -> writeValue ((uint8_t ) notificationOff, 2, true);  and the // pRemoteCharacteristic_THB-> getDescriptor (BLEUUID ((uint16_t) 0x2902)) -> writeValue ((uint8_t ) notificationOn, 2, true); In this case, and after several days, NO error occurs. 2.- Cancel only the loop () off command, canceling the programming line // pRemoteCharacteristic_THB-> getDescriptor (BLEUUID ((uint16_t) 0x2902)) -> writeValue ((uint8_t *) notificationOff, 2, true);  In this case, and after several days, no error occurs either.

Therefore, the error occurs when both commands are used in loop ().

By the way, no additional information of the origin of the problem is obtained if I copy the error message in the Exception Decoder in the ArduinoIDE If I activate the Core Debug Level option in Verbose mode, the messages are not enlightening either

Please can you give me some idea to locate my fault. Am I using the BLE library commands correctly? Thanks in advance

Sketch:


//https://github.com/karolkalinski/esp32-snippets
//https://randomnerdtutorials.com/esp32-bluetooth-low-energy-ble-arduino-ide/
//https://medium.com/home-wireless/how-to-program-an-esp32-in-arduino-while-using-esp-idf-functions-90033d860f75
#define BTU_TASK_STACK_SIZE (6144 + BT_TASK_EXTRA_STACK_SIZE)
#include <BLEDevice.h>
#include <Esp.h>

//#define LYWSD03MMC_ADDR "a4:c1:38:06:78:d8"
#define LYWSD03MMC_ADDR "a4:c1:38:89:78:1c"

BLEClient* pClient;
static BLEAddress htSensorAddress(LYWSD03MMC_ADDR);

bool connectionSuccessful = false;

// The remote service we wish to connect to.
static BLEUUID serviceUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6");
// La caracteristica para cambiar el tiempo de intervalo de comunicaciones.
static BLEUUID charUUID_SetCommInterval("ebe0ccd8-7a0a-4b0c-8a1a-6ff2997da3a6");
static BLEUUID charUUID_SetNotify("00002902-0000-1000-8000-00805f9b34fb");

// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService;
// Obtain a reference to the characteristic in the service of the remote BLE server.
BLERemoteCharacteristic* pRemoteCharacteristic_THB;

const uint8_t notificationOff[] = {0x0, 0x0};
const uint8_t notificationOn[] = {0x1, 0x0};

bool Nueva_Notificacion=false;
float temp;
float humi;
float bat;

/*Log App nRF 
Disabling notifications for ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6
gatt.setCharacteristicNotification(ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6, false)
gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0000)
Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 00-00

Enabling notifications for ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6
gatt.setCharacteristicNotification(ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6, true)
gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0100)
Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
*/

class MyClientCallback : public BLEClientCallbacks 
{
    void onConnect(BLEClient* pclient) {Serial.println("Connected");}
    void onDisconnect(BLEClient* pclient)
    { //Siempre se activa este evento cuando no conecta en la conexion de setup
      Serial.println("Disconnected");connectionSuccessful=false;
      //if (!connectionSuccessful) {Serial.println("RESTART");delay(5000);ESP.restart();}
    }
};

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic_THB,
  uint8_t* pData,
  size_t length,
  bool isNotify) 
  {
  //Serial.print("Notify callback for characteristic ");
  //Serial.println(pBLERemoteCharacteristic->getUUID().toString().c_str());
  Serial.printf("T= %#02x %#02x : H= %#02x : BatmV= %#02x %#02x \n", pData[0], pData[1], pData[2], pData[3], pData[4] );
  temp = (pData[0] | (pData[1] << 8)) * 0.01; //little endian
  humi = pData[2];
  bat = (pData[3] | (pData[4] << 8)) * 0.001; //little endian. Dato en mV y se pasa a voltios
  //Serial.printf("temp= %.2f ºC : humidity= %.2f \% : bat= %.3f v : TempRocio= %.2f ºC \n\n", temp, humi, bat, dewPointC(temp, humi));
  //pClient->disconnect();

  Nueva_Notificacion=true;
  }

void registerNotification() {
  // Obtain a reference to the service we are after in the remote BLE server.
  //BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
  pRemoteService = pClient->getService(serviceUUID);  
  if (pRemoteService == nullptr) {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    pClient->disconnect();
  }
  Serial.println(" - Found our service");

  // Obtain a reference to the characteristic in the service of the remote BLE server.
  //BLERemoteCharacteristic* pRemoteCharacteristic_THB = pRemoteService->getCharacteristic(charUUID);
  pRemoteCharacteristic_THB = pRemoteService->getCharacteristic(charUUID);  
  if (pRemoteCharacteristic_THB == nullptr) {
    Serial.print("Failed to find our characteristic UUID: ");
    Serial.println(charUUID.toString().c_str());
    pClient->disconnect();
  }
  Serial.println(" - Found our characteristic");
  pRemoteCharacteristic_THB->registerForNotify(notifyCallback);
}
// before setup()   https://github.com/nkolban/esp32-snippets/issues/735
static void my_gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* param) {
  ESP_LOGW(LOG_TAG, "custom gattc event handler, event: %d", (uint8_t)event);
        if(event == ESP_GATTC_DISCONNECT_EVT) {
                Serial.print("Disconnect reason: "); 
                Serial.println((int)param->disconnect.reason);
        }
}

unsigned long long currentMillis;
unsigned long long previousMillis;
unsigned long long interval = 60000000; //Lee T/H/Bat cada 1 minuto por notificaciones
unsigned long long looptime;
unsigned long long looptimeMax;
unsigned long long looptimeMin=1000000; //Valor de referencia max.
void setup() {
  Serial.begin(115200); 
  //Serial.begin(921600); 
  ESP32_info();

  Serial.println("Starting Mijia client...");
  BLEDevice::setCustomGattcHandler(my_gattc_event_handler);  // before BLEDevice::init();https://github.com/nkolban/esp32-snippets/issues/735
  BLEDevice::init("ESP32");
  createBleClientWithCallbacks();

  connectionSuccessful = false;
  previousMillis = micros();
}

void loop() 
{
  //currentMillis = millis();
  currentMillis = micros();  
  looptime = currentMillis;

  if (!connectionSuccessful){ Serial.println("Reconectar...."); connectSensor(); Serial.println("Reconectado y registrado"); }
  else
  {
    if(Nueva_Notificacion==true)
    {
      Nueva_Notificacion=false; 
      pRemoteCharacteristic_THB->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOff, 2, true);    
      Serial.printf("temp= %.2f ºC : humidity= %.2f \% : bat= %.3f v : TempRocio= %.2f ºC \n", temp, humi, bat, dewPointC(temp, humi));
      Serial.print("Notifications turned off ->"); Serial.printf("esp_get_free_heap_size: %d \n\n", esp_get_free_heap_size());
    }
    else
    if ( ((currentMillis - previousMillis) > interval) ) 
    {
      Serial.printf("Notifications turned on ->esp_get_free_heap_size: %d \n", esp_get_free_heap_size()); 
      pRemoteCharacteristic_THB->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
      previousMillis = currentMillis;
      Serial.println( micros());    
    }     
  }

  //looptime = millis() - looptime;
  looptime = micros() - looptime;   
  if (looptime > looptimeMax){ looptimeMax= looptime;Serial.printf("LooptimeMax: %d \n", looptimeMax);}
  if (looptime < looptimeMin){ looptimeMin= looptime;Serial.printf("LooptimeMin: %d \n", looptimeMin);}
  //if (looptime >= 1000){ Serial.printf("Looptime > 1s: %d \n", looptime);}  //Indica si el "loop" dura mas de 1 s.
  if (looptime >= 1000000){ Serial.printf("Looptime > 1s: %d \n", looptime);}  //Indica si el "loop" dura mas de 1 s.  
}

void createBleClientWithCallbacks() 
{
  pClient = BLEDevice::createClient();
  pClient->setClientCallbacks(new MyClientCallback());
}

void connectSensor() 
{
  pClient->connect(htSensorAddress);
  //BLEAddress pClient->getPeerAddress();
  String BLE_address= pClient->getPeerAddress().toString().c_str();
  if(pClient->isConnected()==true)
  {
    connectionSuccessful = true;
    Serial.print("BLE_address= ");Serial.print(BLE_address); Serial.printf(" ->Rssi= %d \n", pClient->getRssi()); //advertisedDevice.getRSSI()
    const uint8_t SetCommInterval[] = {0xf4, 0x01};  //Intervalo de comunicacion= 0x01F4 = 500ms. Es el maximo en formato endian littel.
    // Obtain a reference to the service we are after in the remote BLE server.
    //BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    pRemoteService = pClient->getService(serviceUUID);

    // Obtain a reference to the characteristic in the service of the remote BLE server.
    BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID_SetCommInterval);
    // Write the value of the characteristic.
    //pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)SetCommInterval, 2, true); 
    pRemoteCharacteristic->writeValue((uint8_t*)SetCommInterval, 2, true); 

    // Obtain a reference to the service we are after in the remote BLE server.
    pRemoteService = pClient->getService(serviceUUID);  
    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic_THB = pRemoteService->getCharacteristic(charUUID);

    registerNotification();      
  }
}
//****************************************************************************//
//  Dew point Section
//****************************************************************************//
//Funcion copiada de la lib: https://github.com/sparkfun/SparkFun_BME280_Arduino_Library/blob/master/src/SparkFunBME280.cpp
// Returns Dew point in DegC
//double BME280::dewPointC(void)
double dewPointC(double celsius, double humidity)
{
  //double celsius = readTempC(); 
  //double humidity = readFloatHumidity();

  // (1) Saturation Vapor Pressure = ESGG(T)
  double RATIO = 373.15 / (273.15 + celsius);
  double RHS = -7.90298 * (RATIO - 1);
  RHS += 5.02808 * log10(RATIO);
  RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
  RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
  RHS += log10(1013.246);
  double VP = pow(10, RHS - 3) * humidity;  // factor -3 is to adjust units - Vapor Pressure SVP * humidity
         // (2) DEWPOINT = F(Vapor Pressure)
  double T = log(VP/0.61078);   // temp var
  return (241.88 * T) / (17.558 - T);
}

//ESP32 info
//https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/Esp.h#L63
void ESP32_info()
{
  Serial.print("C++ version: "); Serial.println(__cplusplus); 
  Serial.printf("SDK_version: %s \n", ESP.getSdkVersion()); 
  Serial.printf("ESP32_ChipRevision: %d \n", ESP.getChipRevision());

uint64_t chipid3 = ESP.getEfuseMac();
uint16_t chip = (uint16_t)(chipid3 >> 32);
  Serial.printf("chip_serial: %04X%08X\n", chip, (uint32_t)chipid3);

String  stringChipId = getMacAddress();Serial.println(stringChipId);

  Serial.printf("ESP32_GetCpuFreqMHz(): %d \n", ESP.getCpuFreqMHz());

  //Internal RAM
  Serial.printf("ESP32_Total heap size: %d \n", ESP.getHeapSize());  //total heap size
  Serial.printf("ESP32_Available heap: %d \n", ESP.getFreeHeap());   //available heap
  Serial.printf("ESP32_Lowest level of free heap since boot: %d \n", ESP.getMinFreeHeap()); //lowest level of free heap since boot
  Serial.printf("ESP32_Largest block of heap that can be allocated at once: %d \n", ESP.getMaxAllocHeap()); //largest block of heap that can be allocated at once

  //Internal FLASH
  Serial.printf("ESP32_FlashChipSize: %d \n", ESP.getFlashChipSize());
  Serial.printf("ESP32_FlashChipSpeed: %d \n", ESP.getFlashChipSpeed());
  //Serial.printf("ESP32_FlashChipMode: %d \n", ESP.getFlashChipMode());   //FlashMode_t
/*
  Serial.printf("ESP32_magicFlashChipSize: %d \n", ESP.magicFlashChipSize());
  Serial.printf("ESP32_magicFlashChipSpeed: %d \n", ESP.magicFlashChipSpeed());
  Serial.printf("ESP32_magicFlashChipMode: %s \n", ESP.magicFlashChipMode());   //FlashMode_t
*/
  Serial.printf("ESP32_SketchSize: %d \n", ESP.getSketchSize());
  Serial.printf("ESP32_SketchMD5: %d \n", ESP.getSketchMD5());    
  Serial.printf("ESP32_FreeSketchSpace: %d \n", ESP.getFreeSketchSpace());

} 

//Call function to get custom Mac address
String getMacAddress() 
{
    uint8_t baseMac[6];
    // Get MAC address for WiFi station
    esp_read_mac(baseMac, ESP_MAC_WIFI_STA);
    char baseMacChr[18] = {0};
    sprintf(baseMacChr, "%02X:%02X:%02X:%02X:%02X:%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
    return String(baseMacChr);
}

Debug Messages:

day_2020-03-26
21:33:08.956 -> C++ version: 201103
21:33:08.956 -> SDK_version: v3.2.3-14-gd3e562907 
21:33:08.956 -> ESP32_ChipRevision: 1 
21:33:08.956 -> chip_serial: 30B24DBF713C
21:33:08.956 -> 3C:71:BF:4D:B2:30
21:33:08.956 -> ESP32_GetCpuFreqMHz(): 240 
21:33:08.956 -> ESP32_Total heap size: 304152 
21:33:08.956 -> ESP32_Available heap: 278312 
21:33:08.956 -> ESP32_Lowest level of free heap since boot: 273524 
21:33:08.989 -> ESP32_Largest block of heap that can be allocated at once: 113792 
21:33:08.989 -> ESP32_FlashChipSize: 4194304 
21:33:08.989 -> ESP32_FlashChipSpeed: 40000000 
21:33:09.536 -> ESP32_SketchSize: 979072 
21:33:10.359 -> ESP32_SketchMD5: 1073514288 
21:33:10.359 -> ESP32_FreeSketchSpace: 1966080 
21:33:10.359 -> Starting Mijia client...
21:33:10.394 -> 
21:33:10.429 -> Brownout detector was triggered
21:33:10.429 -> 
21:33:10.429 -> ets Jun  8 2016 00:22:57
21:33:10.429 -> 
21:33:10.429 -> rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
21:33:10.429 -> configsip: 0, SPIWP:0xee
21:33:10.429 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
21:33:10.429 -> mode:DIO, clock div:2
21:33:10.429 -> load:0x3fff0018,len:4
21:33:10.429 -> load:0x3fff001c,len:1044
21:33:10.429 -> load:0x40078000,len:8896
21:33:10.429 -> load:0x40080400,len:5828
21:33:10.429 -> entry 0x400806ac
21:33:10.871 -> C++ version: 201103
21:33:10.871 -> SDK_version: v3.2.3-14-gd3e562907 
21:33:10.871 -> ESP32_ChipRevision: 1 
21:33:10.871 -> chip_serial: 30B24DBF713C
21:33:10.871 -> 3C:71:BF:4D:B2:30
21:33:10.871 -> ESP32_GetCpuFreqMHz(): 240 
21:33:10.871 -> ESP32_Total heap size: 304152 
21:33:10.871 -> ESP32_Available heap: 278312 
21:33:10.871 -> ESP32_Lowest level of free heap since boot: 273524 
21:33:10.871 -> ESP32_Largest block of heap that can be allocated at once: 113792 
21:33:10.904 -> ESP32_FlashChipSize: 4194304 
21:33:10.904 -> ESP32_FlashChipSpeed: 40000000 
21:33:11.451 -> ESP32_SketchSize: 979072 
21:33:12.265 -> ESP32_SketchMD5: 1073514288 
21:33:12.265 -> ESP32_FreeSketchSpace: 1966080 
21:33:12.265 -> Starting Mijia client...
21:33:12.982 -> Reconectar....
21:33:16.702 -> Connected
21:33:16.702 -> BLE_address= a4:c1:38:89:78:1c ->Rssi= -63 
21:33:18.843 ->  - Found our service
21:33:18.877 ->  - Found our characteristic
21:33:18.877 -> Reconectado y registrado
21:33:18.877 -> LooptimeMax: 5879913 
21:33:18.877 -> Looptime > 1s: 5879913 
21:33:18.877 -> LooptimeMin: 32 
21:33:18.877 -> LooptimeMin: 1 
21:33:22.360 -> T= 0x3f 0x8 : H= 0x3f : BatmV= 0xce 0xb 
21:33:22.360 -> temp= 21.11 ºC : humidity= 63.00 : bat= 3.022 v : TempRocio= 13.81 ºC 
21:33:22.360 -> Notifications turned off ->esp_get_free_heap_size: 107424 
21:33:22.395 -> 
21:34:01.145 -> LooptimeMin: 0 
21:34:12.969 -> Notifications turned on ->esp_get_free_heap_size: 108256 
21:34:12.969 -> 62154419
21:34:16.377 -> T= 0x41 0x8 : H= 0x3f : BatmV= 0xce 0xb 
21:34:16.377 -> temp= 21.13 ºC : humidity= 63.00 : bat= 3.022 v : TempRocio= 13.83 ºC 
21:34:16.377 -> Notifications turned off ->esp_get_free_heap_size: 107448 
21:34:16.377 -> 
.
.
.
.
day_2020-03-27
14:14:48.346 -> 
14:15:20.655 -> Notifications turned on ->esp_get_free_heap_size: 108256 
14:15:20.655 -> 198
14:15:21.823 -> T= 0xd2 0x8 : H= 0x34 : BatmV= 0xcd 0xb 
14:15:21.823 -> temp= 22.58 ºC : humidity= 52.00 : bat= 3.021 v : TempRocio= 12.25 ºC 
14:15:21.823 -> Notifications turned off ->esp_get_free_heap_size: 107412 
14:15:21.823 -> 
14:15:28.834 -> T= 0xd7 0x8 : H= 0x34 : BatmV= 0xcd 0xb 
14:15:28.834 -> temp= 22.63 ºC : humidity= 52.00 : bat= 3.021 v : TempRocio= 12.29 ºC 
14:15:28.834 -> Notifications turned off ->esp_get_free_heap_size: 107336 
14:15:28.834 -> 
14:15:35.325 -> T= 0xd4 0x8 : H= 0x34 : BatmV= 0xcd 0xb 
14:15:35.325 -> temp= 22.60 ºC : humidity= 52.00 : bat= 3.021 v : TempRocio= 12.27 ºC 
14:15:35.325 -> Notifications turned off ->esp_get_free_heap_size: 107260 
14:15:35.325 -> 
14:15:42.324 -> T= 0xd3 0x8 : H= 0x34 : BatmV= 0xcd 0xb 
14:15:42.324 -> temp= 22.59 ºC : humidity= 52.00 : bat= 3.021 v : TempRocio= 12.26 ºC 
14:15:42.324 -> Notifications turned off ->esp_get_free_heap_size: 107184 
14:15:42.324 -> 
14:15:48.810 -> T= 0xd3 0x8 : H= 0x34 : BatmV= 0xcd 0xb 
14:15:48.810 -> temp= 22.59 ºC : humidity= 52.00 : bat= 3.021 v : TempRocio= 12.26 ºC 
14:15:48.810 -> Notifications turned off ->esp_get_free_heap_size: 107108 
14:15:48.844 -> 
14:15:50.650 -> 
14:15:50.650 -> Stack smashing protect failure!
14:15:50.650 -> 
14:15:50.650 -> Guru Meditation Error: Core  1 panic'ed (Unhandled debug exception)
14:15:50.650 -> Debug exception reason: BREAK instr 
14:15:50.650 -> Core 1 register dump:
14:15:50.650 -> PC      : 0x00000000  PS      : 0x00000000  A0      : 0x00000000  A1      : 0x800d282a  
14:15:50.650 -> A2      : 0x3ffc8730  A3      : 0x01c9d2ae  A4      : 0x28ddf108  A5      : 0x00000004  
14:15:50.683 -> A6      : 0x00000000  A7      : 0x00000000  A8      : 0x3ffc6860  A9      : 0x800d84d0  
14:15:50.683 -> A10     : 0x3ffc8750  A11     : 0x28ddf108  A12     : 0x00000000  A13     : 0x00000001  
14:15:50.683 -> A14     : 0x00000000  A15     : 0x3ffc86ec  SAR     : 0x3ffc86ec  EXCCAUSE: 0x00000001  
14:15:50.683 -> EXCVADDR: 0xffffffe0  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff  
14:15:50.717 -> 
14:15:50.717 -> Backtrace: 0x00000000:0x800d282a
14:15:50.717 -> 
14:15:50.717 -> Rebooting...
chegewara commented 4 years ago

You are not doing anything wrong. Default task in arduino is looperTask, which is created by arduino implementation. It has 8kB stack, which seems to be too few in your case, thats why you get this error: Stack smashing protect failure!

You can create new task, let say at the very beginning of setup and use it instead of loop, in the next line you could just destroy default task to reclaim memory from task stack with vTaskDelete(NULL). Since now setup and loop no longer exist.

jaggil commented 4 years ago

Thank you for your suggestion @chegewara. Before trying to create another task, I thought about monitoring the changes taking place in the stack. This is why I have introduced the "uxTaskGetStackHighWaterMark (NULL)" function before and after the BLE write commands. As you can see, the unused stack size is 6068, which seems quite large. The problem persists, but now the message is associated with "core 0" which surprises me. Does the BLE library run on "core 0"? Now we have some information in the Exception Decoder in the ArduinoIDE about "btagattc" It appears that there are some stored BLE write commands that are pending execution. Is there an easy way in the BLE library to check that the write function has been fully executed?

what's your opinion about it? Thanks in advance

Sketch:


void loop() 
{
  //currentMillis = millis();
  currentMillis = micros();  
  looptime = currentMillis;
  UBaseType_t uxHighWaterMark;

  if (!connectionSuccessful){ Serial.println("Reconectar...."); connectSensor(); Serial.println("Reconectado y registrado"); }
  else
  {
    if(Nueva_Notificacion==true)
    {
      Nueva_Notificacion=false; 
      uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL);Serial.println( uxHighWaterMark);
      pRemoteCharacteristic_THB->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOff, 2, true);    
      uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );Serial.println( uxHighWaterMark);
      Serial.printf("temp= %.2f ºC : humidity= %.2f \% : bat= %.3f v : TempRocio= %.2f ºC \n", temp, humi, bat, dewPointC(temp, humi));
      Serial.print("Notifications turned off ->"); Serial.printf("esp_get_free_heap_size: %d \n\n", esp_get_free_heap_size());
    }
    else
    if ( ((currentMillis - previousMillis) > interval) ) 
    {
      uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
      Serial.printf("Notifications turned on ->esp_get_free_heap_size: %d : %d \n", esp_get_free_heap_size(), uxHighWaterMark); 
      pRemoteCharacteristic_THB->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
      uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );Serial.println( uxHighWaterMark);
      previousMillis = currentMillis;
      Serial.println( micros());    
    }     
  }

  //looptime = millis() - looptime;
  looptime = micros() - looptime;   
  if (looptime > looptimeMax){ looptimeMax= looptime;Serial.printf("LooptimeMax: %d \n", looptimeMax);}
  if (looptime < looptimeMin){ looptimeMin= looptime;Serial.printf("LooptimeMin: %d \n", looptimeMin);}
  //if (looptime >= 1000){ Serial.printf("Looptime > 1s: %d \n", looptime);}  //Indica si el "loop" dura mas de 1 s.
  if (looptime >= 1000000){ Serial.printf("Looptime > 1s: %d \n", looptime);}  //Indica si el "loop" dura mas de 1 s.  
}

Debug Messages:

01:11:52.672 -> 
01:12:47.180 -> Notifications turned on ->esp_get_free_heap_size: 108292 : 6068 
01:12:47.180 -> 6068
01:12:47.180 -> 1562100982
01:12:48.662 -> T= 0xca 0x7 : H= 0x45 : BatmV= 0xcf 0xb 
01:12:48.662 -> 6068
01:12:48.662 -> 6068
01:12:48.662 -> temp= 19.94 ºC : humidity= 69.00 : bat= 3.023 v : TempRocio= 14.10 ºC 
01:12:48.662 -> Notifications turned off ->esp_get_free_heap_size: 107456 
01:12:48.696 -> 
01:12:56.678 -> T= 0xc9 0x7 : H= 0x45 : BatmV= 0xcf 0xb 
01:12:56.678 -> 6068
01:12:56.678 -> 6068
01:12:56.678 -> temp= 19.93 ºC : humidity= 69.00 : bat= 3.023 v : TempRocio= 14.09 ºC 
01:12:56.678 -> Notifications turned off ->esp_get_free_heap_size: 107380 
01:12:56.678 -> 
01:13:03.656 -> T= 0xcb 0x7 : H= 0x45 : BatmV= 0xcf 0xb 
01:13:03.656 -> 6068
01:13:03.656 -> 6068
01:13:03.656 -> temp= 19.95 ºC : humidity= 69.00 : bat= 3.023 v : TempRocio= 14.11 ºC 
01:13:03.689 -> Notifications turned off ->esp_get_free_heap_size: 107304 
01:13:03.689 -> 
01:13:11.146 -> T= 0xcc 0x7 : H= 0x45 : BatmV= 0xcf 0xb 
01:13:11.179 -> 6068
01:13:11.179 -> 6068
01:13:11.179 -> temp= 19.96 ºC : humidity= 69.00 : bat= 3.023 v : TempRocio= 14.12 ºC 
01:13:11.179 -> Notifications turned off ->esp_get_free_heap_size: 107228 
01:13:11.179 -> 
01:13:17.176 -> /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c:3091 (xTaskRemoveFromEventList)- assert failed!
01:13:17.176 -> abort() was called at PC 0x4008fa5a on core 0
01:13:17.176 -> 
01:13:17.176 -> Backtrace: 0x4009165c:0x3ffbe210 0x4009188d:0x3ffbe230 0x4008fa5a:0x3ffbe250 0x4008dcbd:0x3ffbe270 0x4008500d:0x3ffbe290 0x4008c3ea:0x3ffbe2b0 0x40088174:0x3ffbe2e0 0x4001792e:0x3ffbe300 0x4008c190:0x3ffbe320 0x4008bd5a:0x3ffbe340 0x4008c4af:0x3ffbe360 0x40084785:0x3ffbe380 0x4011c3c9:0x3ffc9820 0x4013cab5:0x3ffc9840 0x4013a102:0x3ffc9ad0 0x4013b899:0x3ffc9af0 0x4013cac7:0x3ffc9d80 0x4013a102:0x3ffca010 0x4013b899:0x3ffca030 0x4013cac7:0x3ffca2c0 0x4013a102:0x3ffca550 0x4013b899:0x3ffca570 0x4013cac7:0x3ffca800 0x4013a102:0x3ffcaa90 0x4013b899:0x3ffcaab0 0x4013cac7:0x3ffcad40 0x4013a102:0x3ffcafd0 0x4013b899:0x3ffcaff0 0x4013cac7:0x3ffcb280 0x4013a102:0x3ffcb510 0x4013b899:0x3ffcb530 0x4013cac7:0x3ffcb7c0 0x4013a102:0x3ffcba50 0x4013b899:0x3ffcba70 0x4013cac7:0x3ffcbd00 0x4013a102:0x3ffcbf90 0x4013b899:0x3ffcbfb0 0x4013cac7:0x3ffcc240 0x4013a102:0x3ffcc4d0 0x4013b899:0x3ffcc4f0 0x4013cac7:0x3ffcc780 0x4013a102:0x3ffcca10 0x4013b899:0x3ffcca30 0x4013cac7:0x3ffcccc0 0x4013a102:0x3ffccf50 0x4013b899:0x3ffccf70 0x4013cac7:0x3ffcd200 0x4013a102:0x3ffcd490 0x4013b899:0x3ffcd4b0 0x4013cac7:0x3ffcd740 0x4013a102:0x3ffcd9d0
01:13:17.277 -> 
01:13:17.277 -> Rebooting...

Decoding stack results
0x4009165c: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x4009188d: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x4008fa5a: xTaskRemoveFromEventList at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 3091
0x4008dcbd: xQueueGiveFromISR at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c line 1367
0x4008500d: semphr_give_from_isr_wrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bt.c line 528
0x4011c3c9: GATTC_Write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/stack/gatt/gatt_api.c line 1005
0x4013cab5: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1163
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
0x4013b899: bta_gattc_pop_command_to_send at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1519
0x4013cac7: bta_gattc_write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_act.c line 1170
0x4013a102: bta_gattc_sm_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/bta/gatt/bta_gattc_main.c line 288
chegewara commented 4 years ago

Thank you for your suggestion @chegewara. Before trying to create another task, I thought about monitoring the changes taking place in the stack. This is why I have introduced the "uxTaskGetStackHighWaterMark (NULL)" function before and after the BLE write commands. As you can see, the unused stack size is 6068, which seems quite large. The problem persists, but now the message is associated with "core 0" which surprises me. Does the BLE library run on "core 0"? Now we have some information in the Exception Decoder in the ArduinoIDE about "btagattc" It appears that there are some stored BLE write commands that are pending execution. Is there an easy way in the BLE library to check that the write function has been fully executed?

what's your opinion about it? Thanks in advance

That was really good idea, because i just assumed the problem is in main loop, but in fact stack smashing could be triggered by other task.

From backtrace i can tell that something bad and unusual i think happen in esp-idf bluetooth stack:

Decoding stack results
0x4009165c: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x4009188d: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x4008fa5a: xTaskRemoveFromEventList at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 3091
0x4008dcbd: xQueueGiveFromISR at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c line 1367
0x4008500d: semphr_give_from_isr_wrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bt.c line 528
0x4011c3c9: GATTC_Write at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/bt/bluedroid/stack/gatt/gatt_api.c line 1005

If its reproducible then i suggest to report it on esp-idf repo with code that can be used to reproduce it if possible. In fact maybe @me-no-dev can pass it to bluetooth team and ask for opinion.

jaggil commented 4 years ago

I think it is reproducible, although it is random and sometimes you have to wait hours. On the other hand, to be sure to reproduce it 100%, perhaps you need to have the Xiaomi-Mijia-LYWSD03MMC device. MijiaTemp2_Util_test.txt

hampshire-al commented 4 years ago

I've run your Arduino sketch on an ESP32 and it has run without the error continuously for about 9 hours.

I attach the output log (I've slightly edited your sketch to use English) and the only issue was a disconnection when I moved the LYWSD03MMC, which resulted in losing the connection briefly.

20200411 MijiaTemp2_Log.txt

I don't know if this helps, but I could not reproduce the error over this period of 9 hours.

jaggil commented 4 years ago

Hello @hampshire-al , First of all, thanks a lot for testing my code. Sorry I haven't answered you before, but I've had the project abandoned for several weeks. Yesterday I recompiled my code and after 16 hours the problem remains the same. Please, could you try it for a longer time, for example one or two days? On the other hand, I would like to know how you have integrated the LYWSD03MMC sensors in your system, and how you access the information. I would also like to know how fast is the consumption of the sensor battery.

Thanks in advance, regards

hampshire-al commented 4 years ago

Hi @jaggil, I've finally picked this up again briefly...
I've moved the code to PlatformIO in Visual Studio Code, which requires a couple of small tweaks, but gives a slightly different log, which may help?

I attach the log: 20200623 Log file.txt

It seems that while the LYWSD03MMC was further away it had a few issues including a Stack Smashing failure, but it all settled down when the ESP32 and the LYWSD03MMC moved closer together. This may have just been a coincidence.

I am also attaching a text file with my PlatformIO version of the code: 20200623 Mijia Temp - VSC Platformio Code.txt

Sorry, haven't had time to run it longer, but maybe this helps a little?

stale[bot] commented 4 years ago

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

stale[bot] commented 4 years ago

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

tuxmartin commented 3 years ago

@jaggil hi, do you have any progress?

I tried your code, but it crash:

ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
C++ version: 201103
SDK_version: v3.2.3-14-gd3e562907 
XTENSA_PORT_VERSION: 1.4.2 
tskKERNEL_VERSION_NUMBER: V8.2.0 
ESP32_ChipRevision: 1 
chip_serial: 886F24286F24
24:6F:28:24:6F:88
ESP32_GetCpuFreqMHz(): 240 
ESP32_Total heap size: 300036 
ESP32_Available heap: 274268 
ESP32_Lowest level of free heap since boot: 268968 
ESP32_Largest block of heap that can be allocated at once: 113792 
ESP32_FlashChipSize: 4194304 
ESP32_FlashChipSpeed: 80000000 
ESP32_SketchSize: 1117024 
ESP32_SketchMD5: 1073518336 
ESP32_FreeSketchSpace: 1310720 
Starting Mijia client...
Reconectar....
Connected
BLE_address= a4:c1:38:16:92:57 ->Rssi= -72 

Stack smashing protect failure!

abort() was called at PC 0x400dbb6c on core 1

Backtrace: 0x4009165c:0x3ffc9550 0x4009188d:0x3ffc9570 0x400dbb6c:0x3ffc9590 0x400d5e6f:0x3ffc95b0 0x400d5e96:0x3ffc9670 0x400d2227:0x0c8a1a6f

Rebooting...
jaggil commented 3 years ago

Hello @tuxmartin , I have not had any progress yet, the program crashes randomly after several hours, I don't know what to do to move forward in any way.

I have stopped my project to integrate several LYWSD03MMC in Blynk

covert- commented 2 years ago

To help others. I resolved this issue by using the ArduinoBLE lib instead of the ESP32_BLE one I was using.