espressif / arduino-esp32

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

ESP going into exception while using BLE #9604

Open haseebzaib opened 6 months ago

haseebzaib commented 6 months ago

Board

ESP32-S3

Device Description

Plain module

Hardware Configuration

Nothing attached to device

Version

v2.0.14

IDE Name

PlatformIO

Operating System

Window 10

Flash frequency

80000000L

PSRAM enabled

yes

Upload speed

115200

Description

Hello everyone.

I have sketch in which simple BLE service is being implemented with 4 of its characteristics. In each characteristic a user input an string and I do operation on that.

The issue I am facing is that, when ever I send the string from any characteristic I get hardfault

And sometimes this hardfault occur and after trying 2 3 times it stops, but it is random for sure.

Now I also increased stack size using this SET_LOOP_TASK_STACK_SIZE(20*1024); but this is not solved.

Sketch

#include <Arduino.h>
#include <SPIFFS.h>
#include <WiFi.h>
#include <ArduinoJson.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Preferences.h>
#include "aws_handling.h"
#include "ble_handling.h"

uint8_t status = 0;

char ssid[50];
char pass[50];

SET_LOOP_TASK_STACK_SIZE(20*1024);
void setup()
{

      blehandling_setup();

}

void loop()
{

      blehandling_loop();
}

/**************************************************************************/

/*This file Handles all the tasks related to BLE  */
/*1)First check if ssid and password are stored inside NVS flash */
/*2)If not then open ble gatt server  */
/*3)U wait for ssid and password from ble  */
/*4)After getting those restart the esp32 and connect to aws*/

#include "ble_handling.h"

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define BLE_RUN 0
#define WIFI_RUN 1
#define SERVICE_UUID "cfc9746f-8c03-4af0-90f9-4697fe03c81a"
#define SERVICE_UUID_2 "9d2eb4a0-a11c-4239-9871-7fbe34536bae"
#define CHARACTERISTIC_UUID_SSID "7687a18b-4358-48cf-91d1-7b5fca5bacae"
#define CHARACTERISTIC_UUID_PASS "b6174e00-5a0c-4326-b0f7-ec0663cd1305"
#define CHARACTERISTIC_UUID_NAME "03ac95eb-38bf-4de4-ae32-47ced60cf2d7"
#define CHARACTERISTIC_UUID_LOCATION "bc7cb6a0-95c3-4a2e-8753-a52da038958c"
#define CHARACTERISTIC_UUID_FLASH "48b79ea3-5cd0-4ab7-9ac5-bbc7c9d57713"

Preferences preferences;

/*GLOBAL Var*/
BLEServer *pServer = NULL;
BLECharacteristic *pSSIDcharac;
BLECharacteristic *pPASScharac;
BLECharacteristic *pNAMEcharac;
BLECharacteristic *pLOCATIONcharac;
BLECharacteristic *pFLASHcharac;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint16_t handle_ssid;
uint16_t handle_pass;
uint16_t handle_name;
uint16_t handle_location;

uint8_t flag_saved = 0;
uint8_t flag_SSID = 0;
uint8_t flag_PASS = 0;
uint8_t flag_NAME = 0;
uint8_t flag_LOCATION = 0;
char SSID[32];
char PASS[32];
char NAME[40];
char LOCATION[40];
String SSID_S;
String PASS_S;
String NAME_S;
String LOCATION_S;

/*CALLBACKS*/

class MyServerCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer *pServer) {
    deviceConnected = true;
  };

  void onDisconnect(BLEServer *pServer) {
    deviceConnected = false;
  }
};

class MyCallbacksSSID : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {

    std::string rxValue = pCharacteristic->getValue();
 //   Serial.println("SSID CALLBACK");
    if (rxValue.length() > 0) {
  //    Serial.println("*********");
  //    Serial.print("Received Value: ");
      // for (int i = 0; i < rxValue.length(); i++) {
      //   Serial.print(rxValue[i]);
      // }

      strcpy(SSID, rxValue.c_str());
   //   Serial.println();
   //   Serial.println("*********");
    }
    flag_SSID = 1;
  }
    void onRead(BLECharacteristic* pCharacteristic)
  {
    std::string str(SSID);
     pCharacteristic->setValue(str);
  }

};

class MyCallbacksPASS : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {

    std::string rxValue = pCharacteristic->getValue();
   // Serial.println("PASS CALLBACK");
    if (rxValue.length() > 0) {
    //  Serial.println("*********");
    //  Serial.print("Received Value: ");
      // for (int i = 0; i < rxValue.length(); i++) {
      //   Serial.print(rxValue[i]);
      // }
      strcpy(PASS, rxValue.c_str());
   //   Serial.println();
   //   Serial.println("*********");
    }
    flag_PASS = 1;
  }
    void onRead(BLECharacteristic* pCharacteristic)
  {
    std::string str(PASS);
     pCharacteristic->setValue(str);
  }

};

class MyCallbacksNAME : public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {

    std::string rxValue = pCharacteristic->getValue();
   // Serial.println("NAME CALLBACK");
    if (rxValue.length() > 0) {
   //   Serial.println("*********");
   //   Serial.print("Received Value: ");
      // for (int i = 0; i < rxValue.length(); i++) {
      //   Serial.print(rxValue[i]);
      // }
      strcpy(NAME, rxValue.c_str());
   //   Serial.println();
   //   Serial.println("*********");
    }
    flag_NAME = 1;
  }

      void onRead(BLECharacteristic* pCharacteristic)
  {
    std::string str(NAME);
     pCharacteristic->setValue(str);
  }
};

class MyCallbacksLOCATION: public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *pCharacteristic) {

    std::string rxValue = pCharacteristic->getValue();
   // Serial.println("Location CALLBACK");
    if (rxValue.length() > 0) {
      // Serial.println("*********");
      // Serial.print("Received Value: ");
      // for (int i = 0; i < rxValue.length(); i++) {
      //   Serial.print(rxValue[i]);
      // }
      strcpy(LOCATION, rxValue.c_str());
    //  Serial.println();
    //  Serial.println("*********");
    }
    flag_LOCATION = 1;
  }
      void onRead(BLECharacteristic* pCharacteristic)
  {
    std::string str(LOCATION);
     pCharacteristic->setValue(str);
  }

};

 void blehandling_loop(void)
{
  if (!deviceConnected && oldDeviceConnected) {
    delay(500);                   // give the bluetooth stack the chance to get things ready
    pServer->startAdvertising();  // restart advertising
    Serial.println("start advertising");
    oldDeviceConnected = deviceConnected;
  }
  // connecting
  if (deviceConnected && !oldDeviceConnected) {
    // do stuff here on connecting
    oldDeviceConnected = deviceConnected;
  }

  if (deviceConnected) {

    if (flag_PASS) {
      // Serial.println("inside flag passs");
      // // preferences.begin("my-app", false);
      // Serial.println(PASS);
     // preferences.putString("password", PASS);
      //   preferences.end();
      flag_PASS = 0;
      flag_saved++;
    }
    if (flag_SSID) {
      // Serial.println("inside flag ssid");
      // Serial.println(SSID);
     // preferences.putString("ssid", SSID);
      flag_SSID = 0;
      flag_saved++;
    }

      if (flag_NAME) {
     // Serial.println("inside flag NAME");
      // preferences.begin("my-app", false);
     // Serial.println(NAME);
     // preferences.putString("name", NAME);
      //   preferences.end();
      flag_NAME = 0;
      flag_saved++;
    }
    if (flag_LOCATION) {
      // Serial.println("inside flag LOCATION");
      // Serial.println(LOCATION);
      //preferences.putString("location", LOCATION);
      flag_LOCATION = 0;
      flag_saved++;
    }

    if (flag_saved >= 4) {
      Serial.println("inside flag saved");
      flag_saved = 0;
      uint8_t data[] = "credentials saved";
               preferences.putString("ssid", SSID);
              preferences.putString("password", PASS);
        preferences.putString("name", NAME);
              preferences.putString("location", LOCATION);
      pFLASHcharac->setValue(data, strlen((const char *)data));
      pFLASHcharac->notify();

      delay(5000);
      ESP.restart();
    }
  }
}
 void blehandling_setup(void)
{

   uint64_t chipid = ESP.getEfuseMac(); // The chip ID is essentially its MAC address(length: 6 bytes).
  uint16_t chip = (uint16_t)(chipid >> 32);
char name[50];

sprintf(name,"ESP32_AWS_%d",chip);

   std::string name_ble(name);

   //name_ble = std::string("ESP32_BLE_" + 53);

  BLEDevice::init(name_ble);
  /* Create the BLE Server*/
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  /*Create BLE service*/
  BLEService *pService = pServer->createService(SERVICE_UUID);
  //BLEService *pService_2 = pServer->createService(SERVICE_UUID_2);

  /*Create BLE characteristic*/
  pSSIDcharac = pService->createCharacteristic(
    CHARACTERISTIC_UUID_SSID,
    BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ); //| BLECharacteristic::PROPERTY_READ
  handle_ssid = pSSIDcharac->getHandle();
  pSSIDcharac->setCallbacks(new MyCallbacksSSID());

  pPASScharac = pService->createCharacteristic(
    CHARACTERISTIC_UUID_PASS,
    BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ);
  handle_pass = pPASScharac->getHandle();
  pPASScharac->setCallbacks(new MyCallbacksPASS());

    pNAMEcharac = pService->createCharacteristic(
    CHARACTERISTIC_UUID_NAME,
    BLECharacteristic::PROPERTY_WRITE);
  handle_name = pPASScharac->getHandle();
  pNAMEcharac->setCallbacks(new MyCallbacksNAME());

    pLOCATIONcharac = pService->createCharacteristic(
    CHARACTERISTIC_UUID_LOCATION,
    BLECharacteristic::PROPERTY_WRITE );
  handle_location = pPASScharac->getHandle();
  pLOCATIONcharac->setCallbacks(new MyCallbacksLOCATION());

  pFLASHcharac = pService->createCharacteristic(
    CHARACTERISTIC_UUID_FLASH,
    BLECharacteristic::PROPERTY_NOTIFY);

  pFLASHcharac->addDescriptor(new BLE2902());

  // Start the service
  pService->start();
 // pService_2->start();
  // Start advertising
  pServer->getAdvertising()->start();
  Serial.println("Waiting a client connection to notify...");
}

uint8_t blehandling_check_wifi_credentials(char *ssid,char *pass)
{
      preferences.begin("my-app", false);

  SSID_S = preferences.getString("ssid", "");
  PASS_S = preferences.getString("password", "");

    if (SSID_S == "" || PASS_S == "") {

        return 0;
    }
    else
    {
         strcpy(ssid, SSID_S.c_str());
         strcpy(pass, PASS_S.c_str());
        return 1;
    }
}

Debug Message

Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception). 
Debug exception reason: Stack canary watchpoint triggered (BTC_TASK)
Core  0 register dump:
PC      : 0x40387463  PS      : 0x00060136  A0      : 0x4037fc5a  A1      : 0x3fcf6050  
A2      : 0x3fcf60c0  A3      : 0x00000000  A4      : 0x00000015  A5      : 0x00000000
A6      : 0x3fcb35e4  A7      : 0x00000000  A8      : 0x00000001  A9      : 0x3fcb5d6c  
A10     : 0x00000042  A11     : 0x000000ba  A12     : 0xfffffd9c  A13     : 0x3fcf6a98
A14     : 0x3c126169  A15     : 0x3c1261bb  SAR     : 0x00000004  EXCCAUSE: 0x00000001  
EXCVADDR: 0x00000000  LBEG    : 0x400556d5  LEND    : 0x400556e5  LCOUNT  : 0xfffffffa

Backtrace: 0x40387460:0x3fcf6050 0x4037fc57:0x3fcf6130 0x420f9d36:0x3fcf6160 0x420ff952:0x3fcf6470 0x420ff98e:0x3fcf6500 0x4201a04a:0x3fcf6540 0x4209a356:0x3fcf6580 0x4200df9d:0x3fcf6600 0x420173ed:0x3fcf68c0 0x42012735:0x3fcf68e0 0x42013169:0x3fcf6940 0x420120be:0x3fcf6960 0x4200f8a5:0x3fcf69c0 0x420480b2:0x3fcf6a20 0x42048681:0x3fcf6a40 0x4206a705:0x3fcf6d40 0x4206c9e3:0x3fcf6d60

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

haseebzaib commented 6 months ago

Also sometimes it works fine, but most of the time it goes into hardfault.

me-no-dev commented 6 months ago

stack overflow in the BTC task.

lbernstone commented 6 months ago

It is unclear in your code where you are starting the BTC_TASK, but that stack needs to be increased. The default size can be changed in RTOS.h.

haseebzaib commented 6 months ago

I was looking for solutions of how to increase stack size for BLE task but I got no solution. I dont use arduino so I did not had an idea that you have to change it directly in the files and there is no way to change in your code.

Anyways I got it working from some other ble library which I found and did the job.

haseebzaib commented 6 months ago

It is unclear in your code where you are starting the BTC_TASK,

I have no idea how does arduino starts this task, this was the example I found everywhere and just modified it for my case. Though I increased the "void loop stack size" but it did nothing.