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.
This commit is contained in:
Scott Shawcroft 2022-05-12 13:18:44 -07:00
parent 72807bb6c5
commit 269d51d023
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
12 changed files with 81 additions and 16 deletions

21
main.c
View File

@ -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();
@ -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) {
@ -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);
@ -888,6 +900,7 @@ int __attribute__((used)) main(void) {
serial_init();
#if CIRCUITPY_BLEIO
bleio_reset();
supervisor_bluetooth_enable_workflow();
supervisor_start_bluetooth();
#endif

View File

@ -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.

View File

@ -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"
@ -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);

View File

@ -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);

View File

@ -283,10 +283,6 @@ void reset_port(void) {
watchdog_reset();
#endif
#if CIRCUITPY_BLEIO
bleio_reset();
#endif
#if CIRCUITPY_WIFI
wifi_reset();
#endif

View File

@ -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"
@ -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) {

View File

@ -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);

View File

@ -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;
}

View File

@ -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.

View File

@ -246,10 +246,6 @@ void reset_port(void) {
timers_reset();
#if CIRCUITPY_BLEIO
bleio_reset();
#endif
#if CIRCUITPY_WATCHDOG
watchdog_reset();
#endif

View File

@ -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);

View File

@ -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);