Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add two stage reset for BLE #6389

Merged
merged 2 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add two stage reset for BLE
This lets the BLE stack run through the wait period after a VM run
when it may be waiting for more writes due to an auto-reload.

User BLE functionality will have their events stopped. Scanning and
advertising is also stopped.
  • Loading branch information
tannewt committed May 12, 2022
commit 269d51d0231cc52e49d81bb42ad76abf61e75a33
21 changes: 17 additions & 4 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
memorymonitor_reset();
#endif

filesystem_flush();
stop_mp();
free_memory(heap);
supervisor_move_memory();
// Disable user related BLE state that uses the micropython heap.
#if CIRCUITPY_BLEIO
bleio_user_reset();
#endif

#if CIRCUITPY_CANIO
common_hal_canio_reset();
Expand All @@ -297,6 +297,12 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
#endif
reset_port();
reset_board();

// Free the heap last because other modules may reference heap memory and need to shut down.
filesystem_flush();
stop_mp();
free_memory(heap);
supervisor_move_memory();
}

STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
Expand Down Expand Up @@ -645,6 +651,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re

// Done waiting, start the board back up.

// We delay resetting BLE until after the wait in case we're transferring
// more files over.
#if CIRCUITPY_BLEIO
bleio_reset();
#endif

// free code allocation if unused
if ((next_code_options & next_code_stickiness_situation) == 0) {
free_memory(next_code_allocation);
Expand Down Expand Up @@ -888,6 +900,7 @@ int __attribute__((used)) main(void) {
serial_init();

#if CIRCUITPY_BLEIO
bleio_reset();
supervisor_bluetooth_enable_workflow();
supervisor_start_bluetooth();
#endif
Expand Down
11 changes: 11 additions & 0 deletions ports/espressif/common-hal/_bleio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@
// #include "common-hal/_bleio/bonding.h"
#include "common-hal/_bleio/ble_events.h"

void bleio_user_reset() {
// Stop any user scanning or advertising.
common_hal_bleio_adapter_stop_scan(&common_hal_bleio_adapter_obj);
common_hal_bleio_adapter_stop_advertising(&common_hal_bleio_adapter_obj);

ble_event_remove_heap_handlers();

// Maybe start advertising the BLE workflow.
supervisor_bluetooth_background();
}

// Turn off BLE on a reset or reload.
void bleio_reset() {
// Set this explicitly to save data.
Expand Down
12 changes: 12 additions & 0 deletions ports/espressif/common-hal/_bleio/ble_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <stdbool.h>
#include <stdio.h>

#include "py/gc.h"
#include "py/misc.h"
#include "py/mpstate.h"
#include "py/runtime.h"
Expand All @@ -44,6 +45,17 @@ void ble_event_reset(void) {
MP_STATE_VM(ble_event_handler_entries) = NULL;
}

void ble_event_remove_heap_handlers(void) {
ble_event_handler_entry_t *it = MP_STATE_VM(ble_event_handler_entries);
while (it != NULL) {
// If the param is on the heap, then delete the handler.
if (HEAP_PTR(it->param)) {
ble_event_remove_handler(it->func, it->param);
}
it = it->next;
}
}

void ble_event_add_handler_entry(ble_event_handler_entry_t *entry,
ble_gap_event_fn *func, void *param) {
ble_event_handler_entry_t *it = MP_STATE_VM(ble_event_handler_entries);
Expand Down
1 change: 1 addition & 0 deletions ports/espressif/common-hal/_bleio/ble_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef struct ble_event_handler_entry {
} ble_event_handler_entry_t;

void ble_event_reset(void);
void ble_event_remove_heap_handlers(void);
void ble_event_add_handler(ble_gap_event_fn *func, void *param);
void ble_event_remove_handler(ble_gap_event_fn *func, void *param);

Expand Down
4 changes: 0 additions & 4 deletions ports/espressif/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,6 @@ void reset_port(void) {
watchdog_reset();
#endif

#if CIRCUITPY_BLEIO
bleio_reset();
#endif

#if CIRCUITPY_WIFI
wifi_reset();
#endif
Expand Down
12 changes: 12 additions & 0 deletions ports/nrf/bluetooth/ble_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "nrf_sdm.h"
#include "nrf_soc.h"
#include "nrfx_power.h"
#include "py/gc.h"
#include "py/misc.h"
#include "py/mpstate.h"

Expand All @@ -56,6 +57,17 @@ void ble_drv_reset() {
sd_flash_operation_status = SD_FLASH_OPERATION_DONE;
}

void ble_drv_remove_heap_handlers(void) {
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
while (it != NULL) {
// If the param is on the heap, then delete the handler.
if (HEAP_PTR(it->param)) {
ble_drv_remove_event_handler(it->func, it->param);
}
it = it->next;
}
}

void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t *entry, ble_drv_evt_handler_t func, void *param) {
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
while (it != NULL) {
Expand Down
1 change: 1 addition & 0 deletions ports/nrf/bluetooth/ble_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ typedef struct ble_drv_evt_handler_entry {
} ble_drv_evt_handler_entry_t;

void ble_drv_reset(void);
void ble_drv_remove_heap_handlers(void);
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param);
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param);

Expand Down
6 changes: 4 additions & 2 deletions ports/nrf/common-hal/_bleio/PacketBuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,11 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, c
!mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
}
if (mp_hal_is_interrupted()) {
return -1;
}
}
if (self->conn_handle == BLE_CONN_HANDLE_INVALID ||
mp_hal_is_interrupted()) {
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return -1;
}

Expand Down
11 changes: 11 additions & 0 deletions ports/nrf/common-hal/_bleio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ void check_sec_status(uint8_t sec_status) {
}
}

void bleio_user_reset() {
// Stop any user scanning or advertising.
common_hal_bleio_adapter_stop_scan(&common_hal_bleio_adapter_obj);
common_hal_bleio_adapter_stop_advertising(&common_hal_bleio_adapter_obj);

ble_drv_remove_heap_handlers();

// Maybe start advertising the BLE workflow.
supervisor_bluetooth_background();
}

// Turn off BLE on a reset or reload.
void bleio_reset() {
// Set this explicitly to save data.
Expand Down
4 changes: 0 additions & 4 deletions ports/nrf/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,6 @@ void reset_port(void) {

timers_reset();

#if CIRCUITPY_BLEIO
bleio_reset();
#endif

#if CIRCUITPY_WATCHDOG
watchdog_reset();
#endif
Expand Down
9 changes: 7 additions & 2 deletions py/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,16 @@
#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / MP_BYTES_PER_OBJ_WORD)
#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK)

#define HEAP_PTR(ptr) ( \
MP_STATE_MEM(gc_pool_start) != 0 /* Not on the heap if it isn't inited */ \
&& ptr >= (void *)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
&& ptr < (void *)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
)

// ptr should be of type void*
#define VERIFY_PTR(ptr) ( \
((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
&& ptr >= (void *)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
&& ptr < (void *)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
&& HEAP_PTR(ptr) \
)

void gc_init(void *start, void *end);
Expand Down
5 changes: 5 additions & 0 deletions shared-bindings/_bleio/__init__.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ extern const mp_obj_type_t mp_type_bleio_BluetoothError;
extern const mp_obj_type_t mp_type_bleio_RoleError;
extern const mp_obj_type_t mp_type_bleio_SecurityError;

// Resets all user created BLE state in preparation for the heap disappearing.
// It will maintain BLE workflow and connections.
void bleio_user_reset(void);

// Completely resets the BLE stack including BLE connections.
void bleio_reset(void);

extern mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj);
Expand Down