Skip to content

core panic with ESP32-C2 #1155

@kokospalme

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

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