Skip to content

Commit 2ce57f3

Browse files
committed
extmod/nimble: Add timeout to deinit.
If the BLE radio stops responding before deinit is called the function can get stuck waiting for an event that is never received, particularly if the radio is external or on a separate core. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
1 parent bee1fd5 commit 2ce57f3

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

extmod/nimble/modbluetooth_nimble.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
static uint8_t nimble_address_mode = BLE_OWN_ADDR_RANDOM;
6161

6262
#define NIMBLE_STARTUP_TIMEOUT 2000
63+
#define NIMBLE_SHUTDOWN_TIMEOUT 500
6364

6465
// Any BLE_HS_xxx code not in this table will default to MP_EIO.
6566
static int8_t ble_hs_err_to_errno_table[] = {
@@ -562,8 +563,19 @@ void mp_bluetooth_nimble_port_shutdown(void) {
562563

563564
ble_hs_stop(&ble_hs_shutdown_stop_listener, ble_hs_shutdown_stop_cb, NULL);
564565

566+
mp_uint_t start = mp_hal_ticks_ms();
565567
while (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
566-
mp_event_wait_indefinite();
568+
if ((mp_hal_ticks_ms() - start) > NIMBLE_SHUTDOWN_TIMEOUT) {
569+
break;
570+
}
571+
mp_event_wait_ms(1);
572+
}
573+
574+
// Failure to correctly shutdown can be detected in application by querying
575+
// BLE().active(), else as part of shutdown sequece will usually be resolved
576+
// after reset anyway.
577+
if (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
578+
DEBUG_printf("mp_bluetooth_nimble_port_shutdown failed: timeout\n");
567579
}
568580
}
569581

@@ -629,13 +641,12 @@ int mp_bluetooth_init(void) {
629641

630642
// Run the scheduler while we wait for stack startup.
631643
// On non-ringbuffer builds (NimBLE on STM32/Unix) this will also poll the UART and run the event queue.
632-
mp_uint_t timeout_start_ticks_ms = mp_hal_ticks_ms();
644+
volatile mp_uint_t start = mp_hal_ticks_ms();
633645
while (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_ACTIVE) {
634-
uint32_t elapsed = mp_hal_ticks_ms() - timeout_start_ticks_ms;
635-
if (elapsed > NIMBLE_STARTUP_TIMEOUT) {
646+
if ((mp_hal_ticks_ms() - start) > NIMBLE_STARTUP_TIMEOUT) {
636647
break;
637648
}
638-
mp_event_wait_ms(NIMBLE_STARTUP_TIMEOUT - elapsed);
649+
mp_event_wait_ms(1);
639650
}
640651

641652
if (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_ACTIVE) {

0 commit comments

Comments
 (0)