8000 extmod/nimble: Add timeout to deinit. · micropython/micropython@9f221d3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9f221d3

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 9f221d3

File tree

7 files changed

+30
-18
lines changed

7 files changed

+30
-18
lines changed

extmod/modbluetooth.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,13 @@ static mp_obj_t bluetooth_ble_make_new(const mp_obj_type_t *type, size_t n_args,
290290
static mp_obj_t bluetooth_ble_active(size_t n_args, const mp_obj_t *args) {
291291
if (n_args == 2) {
292292
// Boolean enable/disable argument supplied, set current state.
293+
int err;
293294
if (mp_obj_is_true(args[1])) {
294-
int err = mp_bluetooth_init();
295-
bluetooth_handle_errno(err);
295+
err = mp_bluetooth_init();
296296
} else {
297-
mp_bluetooth_deinit();
297+
err = mp_bluetooth_deinit();
298298
}
299+
bluetooth_handle_errno(err);
299300
}
300301
// Return current state.
301302
return mp_obj_new_bool(mp_bluetooth_is_active());

extmod/modbluetooth.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ extern const mp_obj_type_t mp_type_bluetooth_uuid;
295295
int mp_bluetooth_init(void);
296296

297297
// Disables the Bluetooth stack. Is a no-op when not enabled.
298-
void mp_bluetooth_deinit(void);
298+
int mp_bluetooth_deinit(void);
299299

300300
// Returns true when the Bluetooth stack is active.
301301
bool mp_bluetooth_is_active(void);

extmod/nimble/modbluetooth_nimble.c

Lines changed: 17 additions & 9 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[] = {
@@ -554,17 +555,23 @@ static void ble_hs_shutdown_stop_cb(int status, void *arg) {
554555

555556
static struct ble_hs_stop_listener ble_hs_shutdown_stop_listener;
556557

557-
void mp_bluetooth_nimble_port_shutdown(void) {
558+
int mp_bluetooth_nimble_port_shutdown(void) {
558559
DEBUG_printf("mp_bluetooth_nimble_port_shutdown (nimble default)\n");
559560
// By default, just call ble_hs_stop directly and wait for the stack to stop.
560561

561562
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_STOPPING;
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+
// Stack had not responded (via ble_hs_shutdown_stop_cb)
570+
return MP_ETIMEDOUT;
571+
}
572+
mp_event_wait_ms(1);
567573
}
574+
return 0;
568575
}
569576

570577
#endif // !MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY
@@ -629,13 +636,12 @@ int mp_bluetooth_init(void) {
629636

630637
// Run the scheduler while we wait for stack startup.
631638
// 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();
639+
mp_uint_t start = mp_hal_ticks_ms();
633640
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) {
641+
if ((mp_hal_ticks_ms() - start) > NIMBLE_STARTUP_TIMEOUT) {
636642
break;
637643
}
638-
mp_event_wait_ms(NIMBLE_STARTUP_TIMEOUT - elapsed);
644+
mp_event_wait_ms(1);
639645
}
640646

641647
if (mp_bluetooth_nimble_ble_state != MP_BLUETOOTH_NIMBLE_BLE_STATE_ACTIVE) {
@@ -659,10 +665,11 @@ int mp_bluetooth_init(void) {
659665
return 0;
660666
}
661667

662-
void mp_bluetooth_deinit(void) {
668+
int mp_bluetooth_deinit(void) {
663669
DEBUG_printf("mp_bluetooth_deinit %d\n", mp_bluetooth_nimble_ble_state);
670+
int ret = 0;
664671
if (mp_bluetooth_nimble_ble_state == MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
665-
return;
672+
return 0;
666673
}
667674

668675
// Must call ble_hs_stop() in a port-specific way to stop the background
@@ -675,7 +682,7 @@ void mp_bluetooth_deinit(void) {
675682

676683
DEBUG_printf("mp_bluetooth_deinit: starting port shutdown\n");
677684

678-
mp_bluetooth_nimble_port_shutdown();
685+
ret = mp_bluetooth_nimble_port_shutdown();
679686
assert(mp_bluetooth_nimble_ble_state == MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF);
680687
} else {
681688
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF;
@@ -692,6 +699,7 @@ void mp_bluetooth_deinit(void) {
692699
#endif< F438 /div>
693700

694701
DEBUG_printf("mp_bluetooth_deinit: shut down\n");
702+
return ret;
695703
}
696704

697705
bool mp_bluetooth_is_active(void) {

extmod/nimble/modbluetooth_nimble.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void mp_bluetooth_nimble_port_hci_deinit(void);
8484
void mp_bluetooth_nimble_port_start(void);
8585

8686
// Tell the port to stop its background task.
87-
void mp_bluetooth_nimble_port_shutdown(void);
87+
int mp_bluetooth_nimble_port_shutdown(void);
8888

8989
// --- Called by the HCI UART layer to let us know when packets have been sent.
9090
void mp_bluetooth_nimble_sent_hci_packet(void);

ports/esp32/mpnimbleport.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ void mp_bluetooth_nimble_port_start(void) {
5858
nimble_port_freertos_init(ble_host_task);
5959
}
6060

61-
void mp_bluetooth_nimble_port_shutdown(void) {
61+
int mp_bluetooth_nimble_port_shutdown(void) {
6262
DEBUG_printf("mp_bluetooth_nimble_port_shutdown\n");
6363

6464
#if MICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS_WITH_INTERLOCK
@@ -79,6 +79,8 @@ void mp_bluetooth_nimble_port_shutdown(void) {
7979

8080
// Mark stack as shutdown.
8181
mp_bluetooth_nimble_ble_state = MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF;
82+
83+
return 0;
8284
}
8385

8486
#endif

ports/unix/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
775775
#endif
776776

777777
#if MICROPY_PY_BLUETOOTH
778-
void mp_bluetooth_deinit(void);
778+
int mp_bluetooth_deinit(void);
779779
mp_bluetooth_deinit();
780780
#endif
781781

ports/zephyr/modbluetooth_zephyr.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ int mp_bluetooth_init(void) {
151151
return 0;
152152
}
153153

154-
void mp_bluetooth_deinit(void) {
154+
int mp_bluetooth_deinit(void) {
155155
DEBUG_printf("mp_bluetooth_deinit %d\n", mp_bluetooth_zephyr_ble_state);
156156
if (mp_bluetooth_zephyr_ble_state == MP_BLUETOOTH_ZEPHYR_BLE_STATE_OFF
157157
|| mp_bluetooth_zephyr_ble_state == MP_BLUETOOTH_ZEPHYR_BLE_STATE_SUSPENDED) {
158-
return;
158+
return 0;
159159
}
160160

161161
mp_bluetooth_gap_advertise_stop();
@@ -170,6 +170,7 @@ void mp_bluetooth_deinit(void) {
170170
mp_bluetooth_zephyr_ble_state = MP_BLUETOOTH_ZEPHYR_BLE_STATE_SUSPENDED;
171171

172172
MP_STATE_PORT(bluetooth_zephyr_root_pointers) = NULL;
173+
return 0;
173174
}
174175

175176
bool mp_bluetooth_is_active(void) {

0 commit comments

Comments
 (0)
0