Hi, We are using Nimble BLE on an Espressif ESP32 project. We are getting frequent crashes due to invalid memory access. It looks like a race condition / threading issue to me, but I can't find much info about using Nimble from different threads (i.e. different tasks in FreeRTOS).
Here's a typical crash log: 0x4012773f: put_le16 at C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/porting/nimble/src/endian.c:24 0x400e77c5: ble_hs_hci_cmd_send at C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c:77 0x400e7819: ble_hs_hci_cmd_send_buf at C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_cmd.c:122 0x400e3611: ble_hs_hci_cmd_tx at C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci.c:304 0x400e386b: ble_hs_hci_util_read_rssi at C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_hs_hci_util.c:96 0x400e1709: ble_gap_conn_rssi at C:/Users/Jeremycb/esp-idf/components/bt/host/nimble/nimble/nimble/host/src/ble_gap.c:5906 0x400dc0d5: RSSIUpdateTask at C:\Users\Jeremycb\esp\wireless-controller\build/../components/wc_bluetooth/wc_ble_services.c:369 0x40092e39: vPortTaskWrapper at C:/Users/Jeremycb/esp-idf/components/freertos/port/xtensa/port.c:168 It looks like a bad pointer (NULL) passed to "put_le16". I've seen 3 different call paths, 2 from my own tasks and one from the task used to start / run Nimble. They all converge at the function "ble_hs_hci_cmd_send_buf", which then calls "ble_hs_hci_cmd_send" "ble_hs_hci_cmd_send" uses "ble_hci_trans_buf_alloc", but looking at the code for the "BLE_HCI_TRANS_BUF_CMD" option, there is only one buffer available, and the comments say that "The controller will only allow one outstanding command". Thus it returns NULL if called from different threads, and results in the crash. Looking through the call paths, I see that we can get there two ways: "ble_hs_hci_cmd_tx" (called from our code and many other places) or "ble_hs_flow_tx_num_comp_pkts" (called from flow event callback, from BLE host task). I looked for a mutex, and found that "ble_hs_hci_cmd_tx" locks ble_hs_hci_mutex, whereas "ble_hs_flow_event_cb" (called by BLE host task) locks ble_hs_mutex (different). Our code is calling "ble_gap_conn_rssi" and "ble_gap_adv_rsp_set_fields" on different tasks / threads, which ultimately call "ble_hs_hci_cmd_tx". So, it looks like it's NOT SAFE to call these functions on another thread. This looks like a bug, otherwise how would these functions be used? ________________________________ This email is confidential and may contain information subject to legal privilege. If you are not the intended recipient please advise us of our error by return e-mail then delete this email and any attached files. You may not copy, disclose or use the contents in any way. The views expressed in this email may not be those of Gallagher Group Ltd or subsidiary companies thereof. ________________________________