8000 Stopping BT stack from scheduled function may hang on stm32 · Issue #10477 · micropython/micropython · GitHub
[go: up one dir, main page]

Skip to content
Stopping BT stack from scheduled function may hang on stm32 #10477
Open
@andreamerello

Description

@andreamerello

I've experienced hang (loop forever inside BT stack) when trying to call ble.active(False) from within a scheduled function. This seems to happen when there are alive connections.

I've looked at the code, and I tracked down this to the following reason:

In bluetooth_nimble_port_shutdown(void), ble_hs_stop() is first invoked; it attempts to terminate any live connection i.e. it initiates the termination process, and registers a listener to be called later on when the connection eventually has terminated.

Then bluetooth_nimble_port_shutdown(void) polls over a volatile flag that is supposed to be set by the former listener.. But this flag gets never set, and the loop lasts forever.

This seems to be due to the fact that the BLE stack doesn't run because we are looping inside a scheduled function, so that the listener never gets invoked.

There is also a timeout mechanism for this, which rely on a "npl_callout", but it seems not working in stm32 port, because those "callouts" seem scheduled by nimble_port_run(void) which seems never called on stm32 port. It even looks like that micropython build succeeds just because the compile optimize-out it, otherwise it fails...

So I see two problems here:

  • The listener that should be invoked when connections are terminated doesn't ever run.
  • The timeout on connection termination doesn't work.

BTW FWIW my current workaround is to invoke mp_bluetooth_hci_poll() inside the above loop, after MICROPY_EVENT_POLL_HOOK - It seems to work, but I'm not sure it's really OK in all cases - and to check for a timeout in the very same loop; I now have something like this

    while (mp_bluetooth_nimble_ble_state !=  MP_BLUETOOTH_NIMBLE_BLE_STATE_OFF) {
        MICROPY_EVENT_POLL_HOOK;
        mp_bluetooth_hci_poll();
        if (mp_hal_ticks_ms() - initial_time > 1000)
            ble_hs_stop_done_workaround();
     }

ble_hs_stop_done_workaround() is just a wrapper around ble_hs_stop_done()

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugportsRelates to multiple ports, or a new/proposed port

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0