Skip to content

core panic with ESP32-C2 #1155

Description

@kokospalme

When I try to run the ble Server example, my MCU is panicing. The example:

#include <Arduino.h>
#include <NimBLEDevice.h>

static NimBLEServer* pServer;

/**  None of these are required as they will be handled by the library with defaults. **
 **                       Remove as you see fit for your needs                        */
class ServerCallbacks : public NimBLEServerCallbacks {
    void onConnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo) override {
        Serial.printf("Client connected:\n%s", connInfo.toString().c_str());

        /**
         *  We can use the connection handle here to ask for different connection parameters.
         *  Args: connection handle, min connection interval, max connection interval
         *  latency, supervision timeout.
         *  Units; Min/Max Intervals: 1.25 millisecond increments.
         *  Latency: number of intervals allowed to skip.
         *  Timeout: 10 millisecond increments.
         */
        pServer->updateConnParams(connInfo.getConnHandle(), 24, 48, 0, 180);
    }

    void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo& connInfo, int reason) override {
        Serial.printf("Client disconnected - start advertising\n");
        NimBLEDevice::startAdvertising();
    }

    void onMTUChange(uint16_t MTU, NimBLEConnInfo& connInfo) override {
        Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, connInfo.getConnHandle());
    }

    /********************* Security handled here *********************/
    uint32_t onPassKeyDisplay() override {
        Serial.printf("Server Passkey Display\n");
        /**
         * This should return a random 6 digit number for security
         *  or make your own static passkey as done here.
         */
        return 123456;
    }

    void onConfirmPassKey(NimBLEConnInfo& connInfo, uint32_t pass_key) override {
        Serial.printf("The passkey YES/NO number: %" PRIu32 "\n", pass_key);
        /** Inject false if passkeys don't match. */
        NimBLEDevice::injectConfirmPasskey(connInfo, true);
    }

    void onAuthenticationComplete(NimBLEConnInfo& connInfo) override {
        /** Check that encryption was successful, if not we disconnect the client */
        if (!connInfo.isEncrypted()) {
            NimBLEDevice::getServer()->disconnect(connInfo.getConnHandle());
            Serial.printf("Encrypt connection failed - disconnecting client\n");
            return;
        }

        Serial.printf("Secured connection to: %s\n", connInfo.getAddress().toString().c_str());
    }
} serverCallbacks;

/** Handler class for characteristic actions */
class CharacteristicCallbacks : public NimBLECharacteristicCallbacks {
    void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override {
        Serial.printf("%s : onRead(), value: %s\n",
                      pCharacteristic->getUUID().toString().c_str(),
                      pCharacteristic->getValue().c_str());
    }

    void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override {
        Serial.printf("%s : onWrite(), value: %s\n",
                      pCharacteristic->getUUID().toString().c_str(),
                      pCharacteristic->getValue().c_str());
    }

    /**
     *  The value returned in code is the NimBLE host return code.
     */
    void onStatus(NimBLECharacteristic* pCharacteristic, int code) override {
        Serial.printf("Notification/Indication return code: %d, %s\n", code, NimBLEUtils::returnCodeToString(code));
    }

    /** Peer subscribed to notifications/indications */
    void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override {
        std::string str  = "Client ID: ";
        str             += connInfo.getConnHandle();
        str             += " Address: ";
        str             += connInfo.getAddress().toString();
        if (subValue == 0) {
            str += " Unsubscribed to ";
        } else if (subValue == 1) {
            str += " Subscribed to notifications for ";
        } else if (subValue == 2) {
            str += " Subscribed to indications for ";
        } else if (subValue == 3) {
            str += " Subscribed to notifications and indications for ";
        }
        str += std::string(pCharacteristic->getUUID());

        Serial.printf("%s\n", str.c_str());
    }
} chrCallbacks;

/** Handler class for descriptor actions */
class DescriptorCallbacks : public NimBLEDescriptorCallbacks {
    void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) override {
        std::string dscVal = pDescriptor->getValue();
        Serial.printf("Descriptor written value: %s\n", dscVal.c_str());
    }

    void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) override {
        Serial.printf("%s Descriptor read\n", pDescriptor->getUUID().toString().c_str());
    }
} dscCallbacks;

void setup(void) {
    Serial.begin(115200);
    Serial.printf("Starting NimBLE Server\n");

    /** Initialize NimBLE and set the device name */
    NimBLEDevice::init("NimBLE");

    /**
     * Set the IO capabilities of the device, each option will trigger a different pairing method.
     *  BLE_HS_IO_DISPLAY_ONLY    - Passkey pairing
     *  BLE_HS_IO_DISPLAY_YESNO   - Numeric comparison pairing
     *  BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing
     */
    // NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); // use passkey
    // NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison

    /**
     *  2 different ways to set security - both calls achieve the same result.
     *  no bonding, no man in the middle protection, BLE secure connections.
     *
     *  These are the default values, only shown here for demonstration.
     */
    // NimBLEDevice::setSecurityAuth(false, false, true);
    // NimBLEDevice::setSecurityAuth(BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM | BLE_SM_PAIR_AUTHREQ_SC);

    pServer = NimBLEDevice::createServer();
    pServer->setCallbacks(&serverCallbacks);

    NimBLEService*        pDeadService = pServer->createService("DEAD");
    NimBLECharacteristic* pBeefCharacteristic =
        pDeadService->createCharacteristic("BEEF",
                                           NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE |
                                               /** Require a secure connection for read and write access */
                                               NIMBLE_PROPERTY::READ_ENC | // only allow reading if paired / encrypted
                                               NIMBLE_PROPERTY::WRITE_ENC  // only allow writing if paired / encrypted
        );

    pBeefCharacteristic->setValue("Burger");
    pBeefCharacteristic->setCallbacks(&chrCallbacks);

    /**
     *  2902 and 2904 descriptors are a special case, when createDescriptor is called with
     *  either of those uuid's it will create the associated class with the correct properties
     *  and sizes. However we must cast the returned reference to the correct type as the method
     *  only returns a pointer to the base NimBLEDescriptor class.
     */
    NimBLE2904* pBeef2904 = pBeefCharacteristic->create2904();
    pBeef2904->setFormat(NimBLE2904::FORMAT_UTF8);
    pBeef2904->setCallbacks(&dscCallbacks);

    NimBLEService*        pBaadService = pServer->createService("BAAD");
    NimBLECharacteristic* pFoodCharacteristic =
        pBaadService->createCharacteristic("F00D", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::NOTIFY);

    pFoodCharacteristic->setValue("Fries");
    pFoodCharacteristic->setCallbacks(&chrCallbacks);

    /** Custom descriptor: Arguments are UUID, Properties, max length of the value in bytes */
    NimBLEDescriptor* pC01Ddsc =
        pFoodCharacteristic->createDescriptor("C01D",
                                              NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_ENC,
                                              20);
    pC01Ddsc->setValue("Send it back!");
    pC01Ddsc->setCallbacks(&dscCallbacks);

    /** Create an advertising instance and add the services to the advertised data */
    NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
    pAdvertising->setName("NimBLE-Server");
    pAdvertising->addServiceUUID(pDeadService->getUUID());
    pAdvertising->addServiceUUID(pBaadService->getUUID());
    /**
     *  If your device is battery powered you may consider setting scan response
     *  to false as it will extend battery life at the expense of less data sent.
     */
    pAdvertising->enableScanResponse(true);
    pAdvertising->start();

    Serial.printf("Advertising Started\n");
}

void loop() {
    /** Loop here and send notifications to connected peers */
    delay(2000);

    if (pServer->getConnectedCount()) {
        NimBLEService* pSvc = pServer->getServiceByUUID("BAAD");
        if (pSvc) {
            NimBLECharacteristic* pChr = pSvc->getCharacteristic("F00D");
            if (pChr) {
                pChr->notify();
            }
        }
    }
}

I get this:

Starting NimBLE Server
Guru Meditation Error: Core  0 panic'ed (Load access fault). Exception was unhandled.

Core  0 register dump:
MEPC    : 0x42002ed8  RA      : 0x42004694  SP      : 0x3fcafef0  GP      : 0x3fca7750  
TP      : 0x3fcaffc0  T0      : 0x42002ea0  T1      : 0xffffffe0  T2      : 0xffffffff  
S0/FP   : 0x3fcde2c8  S1      : 0x00000006  A0      : 0x3fcde2c8  A1      : 0x3c04219c  
A2      : 0x00000006  A3      : 0x00000000  A4      : 0x00000006  A5      : 0x00000000  
A6      : 0x1fffffff  A7      : 0xbeef0010  S2      : 0x00000006  S3      : 0x3fcde2f0  
S4      : 0x3fca7000  S5      : 0x3c04219c  S6      : 0x3fcde254  S7      : 0x00000000  
S8      : 0x00000000  S9      : 0x00000000  S10     : 0x00000000  S11     : 0x00000000  
T3      : 0x00000020  T4      : 0x00000000  T5      : 0x00000000  T6      : 0x00000000  
MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000005  MTVAL   : 0x000000a0  
MHARTID : 0x00000000  

Stack memory:
3fcafef0: 0x3fcde254 0x00000000 0x00000000 0x00000000 0x3c04219c 0x00000006 0x3fcde2c8 0x42004694
3fcaff10: 0x3fcaa000 0x3c04219c 0x3fcde2c8 0x420187c8 0x3fcaa000 0x3fcde2ac 0x3fca9214 0x4201b476
3fcaff30: 0x00000000 0x00000000 0x3fcaff40 0x00000006 0x426d694e 0x3f00454c 0x00000013 0x00000014
3fcaff50: 0x00000000 0x3fca8d58 0x00000001 0x420197e6 0x00000000 0x00000000 0x00000000 0x00000000
3fcaff70: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x3fcaa000 0x4201b58e
3fcaff90: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
3fcaffb0: 0x00000000 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5 0x00000000 0x3fca7204 0x3fca71b4 0x3fca71b4
3fcaffd0: 0xa5a5a5a5 0x0002cb95 0x3fcaa844 0x3fcaa844 0x8a644d50 0xa8ea5282 0xb09bb82f 0x69009cad
3fcafff0: 0xa9fe2e84 0x77b80d43 0x0202f24a 0x4906d8e1 0xc2bbd732 0x04c5bf46 0xec9ca699 0x2651c12f
3fcb0010: 0x817afb6c 0xedf484e6 0x708aabbf 0x277bb205 0x219dc355 0x85283d7d 0x548a67ee 0xce89a1a9
3fcb0030: 0x4201d5b7 0xa7d3c102 0x3adcae69 0x6ac16560 0xb330e111 0x6733dfab 0x8ee97948 0x5f0c5cd2
3fcb0050: 0xbf079cee 0xe6744e48 0x0911cbb4 0x6274b054 0x7e2ec7c4 0x15f89e95 0x26eff3e4 0x03018a50
3fcb0070: 0x386dd66f 0x72cd0cea 0x5817ba8a 0xc31c99da 0xefca5033 0xf80447fb 0x990e13c1 0x7f23a9ea
3fcb0090: 0x537dadf3 0xee3f324d 0xe5453f6e 0xdbfeb53e 0x7fb50993 0xc82adca6 0x4e428808 0xba1c55bc
3fcb00b0: 0x0f8c6a24 0x7f5567cb 0x51716993 0xb6f6cfa0 0x9ab10169 0x018a7ff2 0x5f5cd1b8 0x38a6715b
3fcb00d0: 0xd4663dfe 0x3a31e489 0xa365450d 0x0ebe069c 0x6e50bf98 0xa250854f 0xf125353c 0x65016fe0
3fcb00f0: 0xc06983eb 0x930e3169 0x5da07de0 0x679c58b4 0x2af60b2c 0x401164e3 0x18593a3e 0xd102d99e
3fcb0110: 0xc12aeca2 0x2f00a14c 0xe8019d98 0xc7c66d0e 0x7f41c2c5 0x62b83964 0x572d3652 0x220b5b3a
3fcb0130: 0x8ab8ee0f 0xb7494857 0x65887455 0xa37e1809 0xee311733 0x7c6553fc 0x90e5a643 0x25065aeb
3fcb0150: 0x953824d8 0xf509a889 0x238df0c9 0x0fbec50d 0x1ac35b4e 0x4ce0bff5 0xb5b33584 0xf799b646
3fcb0170: 0x020cadb2 0x3ab408c8 0x4dd7e1e4 0x3e897040 0xe7bc92aa 0xaf143ef1 0xc1df738a 0x366a807c
3fcb0190: 0x0f93d490 0x0e42a606 0x1921b69a 0x73d30eb7 0xdc746e91 0x0c5d91b5 0x1f4f34df 0x25556478
3fcb01b0: 0x3240d2df 0xe5892080 0xad13a97b 0xd96e98ef 0xf4775009 0x3d253207 0xde771001 0x2a3134fe
3fcb01d0: 0x9219763a 0xaf97a799 0xa2863cf5 0x366052bd 0x1bfbc9ea 0x3a58f559 0x7ddd8a60 0x30fd37cc
3fcb01f0: 0xd1300e25 0x37c75ce9 0x2426297f 0xa8a7530a 0x4efd9d96 0xf082cdfc 0x54dee145 0x716c8065
3fcb0210: 0xe0a2295b 0x7df298b9 0x768e5442 0x43852c24 0xeecc4241 0x9915af7e 0xb1ff3db6 0x2d0fe77e
3fcb0230: 0x0e8b4ef0 0x20d22e9b 0x6873e6b3 0xca8e0311 0x369fb715 0x70482be4 0x28f56273 0xe4f3423e
3fcb0250: 0x18549f23 0xc45b05b2 0x916bfdf6 0xece329e1 0x9cf1a8da 0x834d0f81 0x78d5322c 0x95a9a7eb
3fcb0270: 0x1dfddfe2 0x54e417b0 0x3f584337 0x1f580398 0x96be0341 0xf059bc3c 0x4c3dc084 0x85d451f5
3fcb0290: 0xb67fee06 0xfb9e41c2 0x06393d47 0x1fd02286 0xf8d625e3 0xb485fcaa 0x5baf1869 0x2615335f
3fcb02b0: 0x1478ce3d 0xc5c0b140 0x28780e90 0x1c8409a4 0x2367180c 0x169abd88 0x24ff071b 0x80e147bc
3fcb02d0: 0x188f90ab 0xaf3e3151 0x6d9af79b 0xaecf418c 0x79e82890 0x6d8ddbf5 0xd6b05cd5 0xdfd8fa6d

this is my platform.ini:

[env:debug]
board_build.flash_size = 2MB
board_build.f_cpu = 160000000L
build_type = debug
platform = espressif32
board = esp32-c2-devkitm-1
framework = arduino
board_build.partitions = partitions.csv
monitor_speed = 115200
build_flags = 
	-DCORE_DEBUG_LEVEL=0
	-DARDUINO_USB_CDC_ON_BOOT=0
	-DAPP_VERSION=\"1.0.0\"
	-DESP32C2
	-Iinclude
lib_compat_mode = strict
lib_deps = 
	h2zero/NimBLE-Arduino @ 2.5.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions