Merge pull request #6389 from tannewt/add_ble_user_reset

Add two stage reset for BLE
This commit is contained in:
Kattni 2022-05-13 14:28:43 -04:00 committed by GitHub
commit 395b550fe3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 89 additions and 16 deletions

View File

@ -57,6 +57,11 @@ bool vm_used_ble;
// } // }
// } // }
void bleio_user_reset() {
// HCI doesn't support the BLE workflow so just do a full reset.
bleio_reset();
}
// Turn off BLE on a reset or reload. // Turn off BLE on a reset or reload.
void bleio_reset() { void bleio_reset() {
// Create a UUID object for all CCCD's. // Create a UUID object for all CCCD's.

21
main.c
View File

@ -277,10 +277,10 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
memorymonitor_reset(); memorymonitor_reset();
#endif #endif
filesystem_flush(); // Disable user related BLE state that uses the micropython heap.
stop_mp(); #if CIRCUITPY_BLEIO
free_memory(heap); bleio_user_reset();
supervisor_move_memory(); #endif
#if CIRCUITPY_CANIO #if CIRCUITPY_CANIO
common_hal_canio_reset(); common_hal_canio_reset();
@ -297,6 +297,12 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
#endif #endif
reset_port(); reset_port();
reset_board(); 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) { 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. // 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 // free code allocation if unused
if ((next_code_options & next_code_stickiness_situation) == 0) { if ((next_code_options & next_code_stickiness_situation) == 0) {
free_memory(next_code_allocation); free_memory(next_code_allocation);
@ -888,6 +900,7 @@ int __attribute__((used)) main(void) {
serial_init(); serial_init();
#if CIRCUITPY_BLEIO #if CIRCUITPY_BLEIO
bleio_reset();
supervisor_bluetooth_enable_workflow(); supervisor_bluetooth_enable_workflow();
supervisor_start_bluetooth(); supervisor_start_bluetooth();
#endif #endif

View File

@ -574,6 +574,9 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool
} }
void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) { void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
if (!common_hal_bleio_adapter_get_advertising(self)) {
return;
}
int err_code = ble_gap_ext_adv_stop(0); int err_code = ble_gap_ext_adv_stop(0);
self->user_advertising = false; self->user_advertising = false;

View File

@ -42,6 +42,17 @@
// #include "common-hal/_bleio/bonding.h" // #include "common-hal/_bleio/bonding.h"
#include "common-hal/_bleio/ble_events.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. // Turn off BLE on a reset or reload.
void bleio_reset() { void bleio_reset() {
// Set this explicitly to save data. // Set this explicitly to save data.

View File

@ -31,6 +31,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include "py/gc.h"
#include "py/misc.h" #include "py/misc.h"
#include "py/mpstate.h" #include "py/mpstate.h"
#include "py/runtime.h" #include "py/runtime.h"
@ -44,6 +45,17 @@ void ble_event_reset(void) {
MP_STATE_VM(ble_event_handler_entries) = NULL; 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, void ble_event_add_handler_entry(ble_event_handler_entry_t *entry,
ble_gap_event_fn *func, void *param) { ble_gap_event_fn *func, void *param) {
ble_event_handler_entry_t *it = MP_STATE_VM(ble_event_handler_entries); 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; } ble_event_handler_entry_t;
void ble_event_reset(void); 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_add_handler(ble_gap_event_fn *func, void *param);
void ble_event_remove_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(); watchdog_reset();
#endif #endif
#if CIRCUITPY_BLEIO
bleio_reset();
#endif
#if CIRCUITPY_WIFI #if CIRCUITPY_WIFI
wifi_reset(); wifi_reset();
#endif #endif

View File

@ -35,6 +35,7 @@
#include "nrf_sdm.h" #include "nrf_sdm.h"
#include "nrf_soc.h" #include "nrf_soc.h"
#include "nrfx_power.h" #include "nrfx_power.h"
#include "py/gc.h"
#include "py/misc.h" #include "py/misc.h"
#include "py/mpstate.h" #include "py/mpstate.h"
@ -56,6 +57,17 @@ void ble_drv_reset() {
sd_flash_operation_status = SD_FLASH_OPERATION_DONE; 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) { 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); ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
while (it != NULL) { while (it != NULL) {

View File

@ -67,6 +67,7 @@ typedef struct ble_drv_evt_handler_entry {
} ble_drv_evt_handler_entry_t; } ble_drv_evt_handler_entry_t;
void ble_drv_reset(void); 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_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); 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()) { !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
if (mp_hal_is_interrupted()) {
return -1;
}
} }
if (self->conn_handle == BLE_CONN_HANDLE_INVALID || if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
mp_hal_is_interrupted()) {
return -1; 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. // Turn off BLE on a reset or reload.
void bleio_reset() { void bleio_reset() {
// Set this explicitly to save data. // Set this explicitly to save data.

View File

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

View File

@ -35,11 +35,16 @@
#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / MP_BYTES_PER_OBJ_WORD) #define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / MP_BYTES_PER_OBJ_WORD)
#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK) #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* // ptr should be of type void*
#define VERIFY_PTR(ptr) ( \ #define VERIFY_PTR(ptr) ( \
((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \ ((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 */ \ && HEAP_PTR(ptr) \
&& ptr < (void *)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
) )
void gc_init(void *start, void *end); 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_RoleError;
extern const mp_obj_type_t mp_type_bleio_SecurityError; 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); void bleio_reset(void);
extern mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj); extern mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj);