espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.58k stars 7.27k forks source link

ESP32 reset after call LVGL delete function inside Nimble event (IDFGH-8826) #10254

Closed jiabuda closed 1 year ago

jiabuda commented 1 year ago

Answers checklist.

General issue report

IDF: 4.4.2 LVGL: 8.3.3 Chip: ESP32

Hi, I am integrating Nimble and LVGL together to build a IOT device. Screen would be updated after Nimble central role discovery a peripheral device and establish connection. So inside Nimble event BLE_GAP_EVENT_CONNECT , I call some lvgl function to switch to another screen and call lv_obj_delto delete the current screen. But the mcu reset and give a confusing core dump.

Here is the code:

case BLE_GAP_EVENT_CONNECT:
        /* A new connection was established or a connection attempt failed. */
        if (event->connect.status == 0)
        {
            /* Connection successfully established. */
            ESP_LOGI(TAG, "Connection established");

            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
            assert(rc == 0);

            /* Remember peer. */
            rc = peer_add(event->connect.conn_handle);
            if (rc != 0)
            {
                ESP_LOGE(TAG, "Failed to add peer; rc=%d", rc);
                return 0;
            }

            /* Perform service discovery. */
            rc = peer_disc_all(event->connect.conn_handle, blecent_on_disc_complete, NULL);
            if (rc != 0)
            {
                ESP_LOGE(TAG, "Failed to discover services; rc=%d", rc);
                return 0;
            }          
        }
        else
        {
            /* Connection attempt failed; resume scanning. */
            ESP_LOGE(TAG, "Error: Connection failed; status=%d", event->connect.status);
        }
        return 0;

and

static void blecent_on_disc_complete(const struct peer *peer, int status, void *arg)
{

    if (status != 0)
    {
        /* Service discovery failed.  Terminate the connection. */
        ESP_LOGE(TAG, "Error: Service discovery failed; status=%d conn_handle=%d", status, peer->conn_handle);
        ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
        return;
    }

    /* Service discovery has completed successfully.  Now we have a complete
     * list of services, characteristics, and descriptors that the peer
     * supports.
     */
    ESP_LOGI(TAG, "Service discovery complete; status=%d conn_handle=%d", status, peer->conn_handle);

    /* Now perform three GATT procedures against the peer: read,
     * write, and subscribe to notifications.
     */
    blecent_subscribe(peer);

    connectCallback(peer->conn_handle);
}

void connectCallback(uint16_t conn_handle)
{
    displayBattleQuestionScreen();
}

void displayBattleQuestionScreen()
{
    battleQuestionScreen = lv_obj_create(NULL);
    board = lv_obj_create(battleQuestionScreen);
    lv_obj_set_style_border_width(board, 0, 0);
    lv_obj_set_style_pad_all(board, 0, 0);
    lv_obj_set_size(board, BLOCK * 4 + GAP * 5, BLOCK * 5 + GAP * 6);
    lv_obj_align(board, LV_ALIGN_TOP_MID, 0, 20);
    gameLabel = lv_label_create(battleQuestionScreen);
    lv_label_set_text(gameLabel, "");
    lv_obj_align_to(gameLabel, board, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 20);

    puzzleParser((uint8_t *)&puzzleList[0], strlen(puzzleList[0]));
    for (int i = 0; i < chessCount; i++)
    {
        lv_obj_t *block = lv_obj_create(board);
        chess_t chess = chessList[i];
        int width = shapeList[chess.shape].width;
        int height = shapeList[chess.shape].height;
        int color = shapeList[chess.shape].color;
        int x = positionList[chess.pos].x;
        int y = positionList[chess.pos].y;
        lv_obj_set_size(block, width, height);
        lv_obj_set_style_radius(block, 4, 0);
        lv_obj_set_style_border_width(block, 0, 0);
        lv_obj_set_style_bg_color(block, lv_color_hex(color), 0);
        lv_obj_set_pos(block, x, y);
        lv_obj_clear_flag(block, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_CLICK_FOCUSABLE);
        blockList[i] = block;
    }
    lv_scr_load(battleQuestionScreen);
    deleteAllScreenExcept(battleQuestionScreen);
}

void deleteAllScreenExcept(lv_obj_t *remain)
{
    if (pairScreen != NULL && pairScreen != remain)
    {
        lv_obj_clean(pairScreen);
        lv_obj_del(pairScreen);
        pairScreen = NULL;
    }

    if (modeChooseScreen != NULL && modeChooseScreen != remain)
    {
        lv_obj_clean(modeChooseScreen);
        lv_obj_del(modeChooseScreen);
        modeChooseScreen = NULL;
    }

    if (battleQuestionScreen != NULL && battleQuestionScreen != remain)
    {
        lv_obj_clean(battleQuestionScreen);
        lv_obj_del(battleQuestionScreen);
        battleQuestionScreen = NULL;
    }
}

here is the stack trace

Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x400fb2ca  PS      : 0x00060730  A0      : 0x800fc2bd  A1      : 0x3ffdad40
0x400fb2ca: _lv_event_mark_deleted at D:/git/giiker/esp32_nimble/components/lvgl/src/core/lv_event.c:156

A2      : 0x3ffc5d20  A3      : 0x3ffc58f8  A4      : 0x00000020  A5      : 0x3ffc5d20
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x00000075  A9      : 0x800d1300
A10     : 0x00000001  A11     : 0x3ffc58f8  A12     : 0x3ffc591c  A13     : 0x00000075
A14     : 0x0000009b  A15     : 0x00000000  SAR     : 0x00000018  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000079  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffff0

Backtrace:0x400fb2c7:0x3ffdad400x400fc2ba:0x3ffdad60 0x4014ff9b:0x3ffdad80 0x4014ffa9:0x3ffdada0 0x40100dc8:0x3ffdadc0 0x40100ef4:0x3ffdade0 0x400fab9e:0x3ffdae00 0x400fa9ae:0x3ffdae20 0x400d5f56:0x3ffdae50 0x400d6515:0x3ffdae70 0x4014f122:0x3ffdaea0 0x400d6c5e:0x3ffdaec0 0x400d6cad:0x3ffdaee0 0x400d8987:0x3ffdaf00 0x400d89bf:0x3ffdaf20 0x400d9cf5:0x3ffdaf40 0x400da2f5:0x3ffdaf60 0x400d858d:0x3ffdaf80 0x400d844e:0x3ffdafb0 0x400d7b45:0x3ffdafe0 0x400d7b57:0x3ffdb000 0x400e06da:0x3ffdb020 0x400d63a6:0x3ffdb040 0x40093cc1:0x3ffdb060
0x400fb2c7: _lv_event_mark_deleted at D:/git/giiker/esp32_nimble/components/lvgl/src/core/lv_event.c:155

0x400fc2ba: lv_obj_destructor at D:/git/giiker/esp32_nimble/components/lvgl/src/core/lv_obj.c:435

0x4014ff9b: _lv_obj_destruct at D:/git/giiker/esp32_nimble/components/lvgl/src/core/lv_obj_class.c:136 (discriminator 1)

0x4014ffa9: _lv_obj_destruct at D:/git/giiker/esp32_nimble/components/lvgl/src/core/lv_obj_class.c:143

0x40100dc8: obj_del_core at D:/git/giiker/esp32_nimble/components/lvgl/src/core/lv_obj_tree.c:389

0x40100ef4: lv_obj_clean at D:/git/giiker/esp32_nimble/components/lvgl/src/core/lv_obj_tree.c:94

0x400fab9e: deleteAllScreenExcept at D:/git/giiker/esp32_nimble/components/screen/screenTotal.c:34

0x400fa9ae: displayBattleQuestionScreen at D:/git/giiker/esp32_nimble/components/screen/battleQuestionScreen.c:101

0x400d5f56: centralConnectCallback at D:/git/giiker/esp32_nimble/components/klotski/game.c:168

0x400d6515: blecent_on_disc_complete at D:/git/giiker/esp32_nimble/components/ble_gatt/central.c:163 (discriminator 13)

0x4014f122: peer_disc_complete at D:/git/giiker/esp32_nimble/components/ble_gatt/peer.c:82

0x400d6c5e: peer_disc_dscs at D:/git/giiker/esp32_nimble/components/ble_gatt/peer.c:211

0x400d6cad: peer_dsc_disced at D:/git/giiker/esp32_nimble/components/ble_gatt/peer.c:235

0x400d8987: ble_gattc_disc_all_dscs_cb at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_gattc.c:2577

0x400d89bf: ble_gattc_disc_all_dscs_err at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_gattc.c:2646

0x400d9cf5: ble_gattc_rx_err at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_gattc.c:4387

0x400da2f5: ble_att_clt_rx_error at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_att_clt.c:46

0x400d858d: ble_att_rx at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_att.c:503

0x400d844e: ble_hs_hci_evt_acl_process at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_evt.c:927

0x400d7b45: ble_hs_process_rx_data_queue at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs.c:238

0x400d7b57: ble_hs_event_rx_data at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs.c:532

0x400e06da: ble_npl_event_run at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/porting/npl/freertos/include/nimble/nimble_npl_os.h:125
 (inlined by) nimble_port_run at C:/Users/Endy/esp/esp-idf/components/bt/host/nimble/nimble/porting/nimble/src/nimble_port.c:78

0x400d63a6: blecent_host_task at D:/git/giiker/esp32_nimble/components/ble_gatt/central.c:377

0x40093cc1: vPortTaskWrapper at C:/Users/Endy/esp/esp-idf/components/freertos/port/xtensa/port.c:131
chegewara commented 1 year ago

Currently I am playing with lvgl and nimble on arduino and S3. With simple screens I have no problem switching between screens. Another application has more extended screens and transition caused crash. Unlucky to me no UART, so no backtrace. It turned out that simple task to handle lvgl was the problem. Running it on core 1 crashed app, now its running on core 0 and all is fine.

jiabuda commented 1 year ago

Currently I am playing with lvgl and nimble on arduino and S3. With simple screens I have no problem switching between screens. Another application has more extended screens and transition caused crash. Unlucky to me no UART, so no backtrace. It turned out that simple task to handle lvgl was the problem. Running it on core 1 crashed app, now its running on core 0 and all is fine.

Hi chegewara, i ask this question in lvgl, they reply that need to take the semaphore when you update the screen then give it again. i try this and problem solved.