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:
parent
72807bb6c5
commit
269d51d023
21
main.c
21
main.c
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
9
py/gc.h
9
py/gc.h
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue