Skip to content

Commit fad755d

Browse files
authored
Merge pull request #9616 from tannewt/fix_c6_crash
Three fixes found for ESP32-C6
2 parents 2581deb + b5517cb commit fad755d

File tree

17 files changed

+121
-39
lines changed

17 files changed

+121
-39
lines changed

devices/ble_hci/common-hal/_bleio/Characteristic.c

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
5050
}
5151
}
5252

53+
bool common_hal_bleio_characteristic_deinited(bleio_characteristic_obj_t *self) {
54+
return self->handle == BLE_GATT_HANDLE_INVALID;
55+
}
56+
57+
void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self) {
58+
if (common_hal_bleio_characteristic_deinited(self)) {
59+
return;
60+
}
61+
self->handle = BLE_GATT_HANDLE_INVALID;
62+
}
63+
5364
mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self) {
5465
return mp_obj_new_tuple(self->descriptor_list->len, self->descriptor_list->items);
5566
}

ports/espressif/common-hal/_bleio/Characteristic.c

+32-32
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "shared-bindings/_bleio/PacketBuffer.h"
1717
#include "shared-bindings/_bleio/Service.h"
1818
#include "shared-bindings/time/__init__.h"
19+
#include "supervisor/shared/safe_mode.h"
1920

2021
#include "common-hal/_bleio/Adapter.h"
2122
#include "common-hal/_bleio/Service.h"
@@ -100,27 +101,20 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
100101
self->flags |= BLE_GATT_CHR_F_WRITE_AUTHEN;
101102
}
102103

103-
if (initial_value_bufinfo != NULL) {
104-
// Copy the initial value if it's on the heap. Otherwise it's internal and we may not be able
105-
// to allocate.
106-
self->current_value_len = initial_value_bufinfo->len;
107-
if (gc_alloc_possible()) {
108-
self->current_value = m_malloc(max_length);
109-
self->current_value_alloc = max_length;
110-
if (gc_nbytes(initial_value_bufinfo->buf) > 0) {
111-
memcpy(self->current_value, initial_value_bufinfo->buf, self->current_value_len);
112-
}
113-
} else {
114-
self->current_value = initial_value_bufinfo->buf;
115-
assert(self->current_value_len == max_length);
116-
}
104+
if (gc_alloc_possible()) {
105+
self->current_value = m_malloc(max_length);
117106
} else {
118107
self->current_value = port_malloc(max_length, false);
119-
if (self->current_value != NULL) {
120-
self->current_value_alloc = max_length;
121-
self->current_value_len = 0;
108+
if (self->current_value == NULL) {
109+
reset_into_safe_mode(SAFE_MODE_NO_HEAP);
122110
}
123111
}
112+
self->current_value_alloc = max_length;
113+
self->current_value_len = 0;
114+
115+
if (initial_value_bufinfo != NULL) {
116+
common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo);
117+
}
124118

125119
if (gc_alloc_possible()) {
126120
self->descriptor_list = mp_obj_new_list(0, NULL);
@@ -140,6 +134,26 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
140134
}
141135
}
142136

137+
bool common_hal_bleio_characteristic_deinited(bleio_characteristic_obj_t *self) {
138+
return self->current_value == NULL;
139+
}
140+
141+
void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self) {
142+
if (common_hal_bleio_characteristic_deinited(self)) {
143+
return;
144+
}
145+
if (self->current_value == NULL) {
146+
return;
147+
}
148+
149+
if (gc_nbytes(self->current_value) > 0) {
150+
m_free(self->current_value);
151+
} else {
152+
port_free(self->current_value);
153+
}
154+
self->current_value = NULL;
155+
}
156+
143157
mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self) {
144158
if (self->descriptor_list == NULL) {
145159
return mp_const_empty_tuple;
@@ -245,21 +259,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
245259
}
246260

247261
self->current_value_len = bufinfo->len;
248-
// If we've already allocated an internal buffer or the provided buffer
249-
// is on the heap, then copy into the internal buffer.
250-
if (self->current_value_alloc > 0 || gc_nbytes(bufinfo->buf) > 0) {
251-
if (self->current_value_alloc < bufinfo->len) {
252-
self->current_value = m_realloc(self->current_value, bufinfo->len);
253-
// Get the number of bytes from the heap because it may be more
254-
// than the len due to gc block size.
255-
self->current_value_alloc = gc_nbytes(self->current_value);
256-
}
257-
memcpy(self->current_value, bufinfo->buf, bufinfo->len);
258-
} else {
259-
// Otherwise, use the provided buffer to delay any heap allocation.
260-
self->current_value = bufinfo->buf;
261-
self->current_value_alloc = 0;
262-
}
262+
memcpy(self->current_value, bufinfo->buf, self->current_value_len);
263263

264264
ble_gatts_chr_updated(self->handle);
265265
}

ports/espressif/common-hal/_bleio/CharacteristicBuffer.c

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ void bleio_characteristic_buffer_extend(bleio_characteristic_buffer_obj_t *self,
2626
for (uint16_t i = 0; i < len; i++) {
2727
if (data[i] == mp_interrupt_char) {
2828
mp_sched_keyboard_interrupt();
29+
ringbuf_clear(&self->ringbuf);
2930
} else {
3031
ringbuf_put(&self->ringbuf, data[i]);
3132
}

ports/espressif/common-hal/_bleio/PacketBuffer.c

+1
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
436436
return;
437437
}
438438
bleio_characteristic_clear_observer(self->characteristic);
439+
self->characteristic = NULL;
439440
ble_event_remove_handler(packet_buffer_on_ble_client_evt, self);
440441
ringbuf_deinit(&self->ringbuf);
441442
}

ports/espressif/supervisor/usb_serial_jtag.c

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static void _copy_out_of_fifo(void) {
4646
for (size_t i = 0; i < len; ++i) {
4747
if (rx_buf[i] == mp_interrupt_char) {
4848
mp_sched_keyboard_interrupt();
49+
ringbuf_clear(&ringbuf);
4950
} else {
5051
ringbuf_put(&ringbuf, rx_buf[i]);
5152
}

ports/nordic/common-hal/_bleio/Characteristic.c

+13
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
109109
}
110110
}
111111

112+
bool common_hal_bleio_characteristic_deinited(bleio_characteristic_obj_t *self) {
113+
return self->handle == BLE_GATT_HANDLE_INVALID;
114+
}
115+
116+
void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self) {
117+
if (common_hal_bleio_characteristic_deinited(self)) {
118+
return;
119+
}
120+
self->handle = BLE_GATT_HANDLE_INVALID;
121+
// TODO: Can we remove this from the soft device? Right now we assume the
122+
// reset clears things.
123+
}
124+
112125
mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self) {
113126
if (self->descriptor_list == NULL) {
114127
return mp_const_empty_tuple;

ports/nordic/common-hal/_bleio/CharacteristicBuffer.c

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *d
2929
for (uint16_t i = 0; i < len; i++) {
3030
if (data[i] == mp_interrupt_char) {
3131
mp_sched_keyboard_interrupt();
32+
ringbuf_clear(&self->ringbuf);
3233
} else {
3334
ringbuf_put(&self->ringbuf, data[i]);
3435
}

ports/silabs/common-hal/_bleio/Characteristic.c

+7
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ void common_hal_bleio_characteristic_construct(
155155
}
156156
}
157157

158+
bool common_hal_bleio_characteristic_deinited(bleio_characteristic_obj_t *self) {
159+
return false;
160+
}
161+
162+
void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self) {
163+
}
164+
158165
// A tuple of Descriptor that describe this characteristic
159166
mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(
160167
bleio_characteristic_obj_t *self) {

py/gc.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -759,13 +759,10 @@ void gc_info(gc_info_t *info) {
759759
GC_EXIT();
760760
}
761761

762-
// CIRCUITPY-CHANGE
762+
// CIRCUITPY-CHANGE: C code may be used when the VM heap isn't active. This
763+
// allows that code to test if it is. It can use the outer pool if needed.
763764
bool gc_alloc_possible(void) {
764-
#if MICROPY_GC_SPLIT_HEAP
765-
return MP_STATE_MEM(gc_last_free_area) != 0;
766-
#else
767765
return MP_STATE_MEM(area).gc_pool_start != 0;
768-
#endif
769766
}
770767

771768
void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) {

shared-bindings/_bleio/Characteristic.c

+28
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "shared-bindings/_bleio/Characteristic.h"
1313
#include "shared-bindings/_bleio/Service.h"
1414
#include "shared-bindings/_bleio/UUID.h"
15+
#include "shared-bindings/util.h"
16+
1517

1618
//| class Characteristic:
1719
//| """Stores information about a BLE service characteristic and allows reading
@@ -137,14 +139,29 @@ static mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
137139
static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_add_to_service_fun_obj, 1, bleio_characteristic_add_to_service);
138140
static MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_characteristic_add_to_service_obj, MP_ROM_PTR(&bleio_characteristic_add_to_service_fun_obj));
139141

142+
//| def deinit(self) -> None:
143+
//| """Deinitialises the Characteristic and releases any hardware resources for reuse."""
144+
//| ...
145+
static mp_obj_t bleio_characteristic_deinit(mp_obj_t self_in) {
146+
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
147+
common_hal_bleio_characteristic_deinit(self);
148+
return mp_const_none;
149+
}
150+
static MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_deinit_obj, bleio_characteristic_deinit);
140151

152+
static void check_for_deinit(bleio_characteristic_obj_t *self) {
153+
if (common_hal_bleio_characteristic_deinited(self)) {
154+
raise_deinited_error();
155+
}
156+
}
141157

142158
//| properties: int
143159
//| """An int bitmask representing which properties are set, specified as bitwise or'ing of
144160
//| of these possible values.
145161
//| `BROADCAST`, `INDICATE`, `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE`."""
146162
static mp_obj_t bleio_characteristic_get_properties(mp_obj_t self_in) {
147163
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
164+
check_for_deinit(self);
148165

149166
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_get_properties(self));
150167
}
@@ -159,6 +176,7 @@ MP_PROPERTY_GETTER(bleio_characteristic_properties_obj,
159176
//| Will be ``None`` if the 128-bit UUID for this characteristic is not known."""
160177
static mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) {
161178
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
179+
check_for_deinit(self);
162180

163181
bleio_uuid_obj_t *uuid = common_hal_bleio_characteristic_get_uuid(self);
164182
return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none;
@@ -172,6 +190,7 @@ MP_PROPERTY_GETTER(bleio_characteristic_uuid_obj,
172190
//| """The value of this characteristic."""
173191
static mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) {
174192
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
193+
check_for_deinit(self);
175194

176195
uint8_t temp[512];
177196
size_t actual_len = common_hal_bleio_characteristic_get_value(self, temp, sizeof(temp));
@@ -181,6 +200,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_chara
181200

182201
static mp_obj_t bleio_characteristic_set_value(mp_obj_t self_in, mp_obj_t value_in) {
183202
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
203+
check_for_deinit(self);
184204

185205
mp_buffer_info_t bufinfo;
186206
mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ);
@@ -199,6 +219,7 @@ MP_PROPERTY_GETSET(bleio_characteristic_value_obj,
199219
//| """The max length of this characteristic."""
200220
static mp_obj_t bleio_characteristic_get_max_length(mp_obj_t self_in) {
201221
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
222+
check_for_deinit(self);
202223

203224
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_get_max_length(self));
204225
}
@@ -211,6 +232,8 @@ MP_PROPERTY_GETTER(bleio_characteristic_max_length_obj,
211232
//| """A tuple of :py:class:`Descriptor` objects related to this characteristic. (read-only)"""
212233
static mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) {
213234
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
235+
check_for_deinit(self);
236+
214237
// Return list as a tuple so user won't be able to change it.
215238
return MP_OBJ_FROM_PTR(common_hal_bleio_characteristic_get_descriptors(self));
216239
}
@@ -224,6 +247,7 @@ MP_PROPERTY_GETTER(bleio_characteristic_descriptors_obj,
224247
//| """The Service this Characteristic is a part of."""
225248
static mp_obj_t bleio_characteristic_get_service(mp_obj_t self_in) {
226249
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
250+
check_for_deinit(self);
227251

228252
return common_hal_bleio_characteristic_get_service(self);
229253
}
@@ -241,6 +265,7 @@ MP_PROPERTY_GETTER(bleio_characteristic_service_obj,
241265
//| ...
242266
static mp_obj_t bleio_characteristic_set_cccd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
243267
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
268+
check_for_deinit(self);
244269

245270
enum { ARG_notify, ARG_indicate };
246271
static const mp_arg_t allowed_args[] = {
@@ -258,6 +283,9 @@ static mp_obj_t bleio_characteristic_set_cccd(mp_uint_t n_args, const mp_obj_t *
258283
static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_characteristic_set_cccd);
259284

260285
static const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = {
286+
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_characteristic_deinit_obj) },
287+
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&bleio_characteristic_deinit_obj) },
288+
261289
{ MP_ROM_QSTR(MP_QSTR_add_to_service), MP_ROM_PTR(&bleio_characteristic_add_to_service_obj) },
262290
{ MP_ROM_QSTR(MP_QSTR_descriptors), MP_ROM_PTR(&bleio_characteristic_descriptors_obj) },
263291
{ MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_properties_obj) },

shared-bindings/_bleio/Characteristic.h

+2
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ extern size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristi
2424
extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t *buf, size_t len);
2525
extern void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor);
2626
extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_buffer_info_t *initial_value_bufinfo, const char *user_description);
27+
extern bool common_hal_bleio_characteristic_deinited(bleio_characteristic_obj_t *self);
28+
extern void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self);
2729
extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
2830
extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);

supervisor/shared/bluetooth/bluetooth.c

+4
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ void supervisor_stop_bluetooth(void) {
339339

340340
ble_started = false;
341341

342+
#if CIRCUITPY_BLE_FILE_SERVICE
343+
supervisor_stop_bluetooth_file_transfer();
344+
#endif
345+
342346
#if CIRCUITPY_SERIAL_BLE
343347
supervisor_stop_bluetooth_serial();
344348
#endif

supervisor/shared/bluetooth/file_transfer.c

+7
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ void supervisor_start_bluetooth_file_transfer(void) {
101101
&static_handler_entry);
102102
}
103103

104+
void supervisor_stop_bluetooth_file_transfer(void) {
105+
common_hal_bleio_packet_buffer_deinit(&_transfer_packet_buffer);
106+
common_hal_bleio_characteristic_deinit(&supervisor_ble_transfer_characteristic);
107+
common_hal_bleio_characteristic_deinit(&supervisor_ble_version_characteristic);
108+
common_hal_bleio_service_deinit(&supervisor_ble_service);
109+
}
110+
104111
#define COMMAND_SIZE 1024
105112

106113
#define ANY_COMMAND 0x00

supervisor/shared/bluetooth/file_transfer.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include <stdbool.h>
1010

11-
void supervisor_bluetooth_file_transfer_background(void);
1211
void supervisor_start_bluetooth_file_transfer(void);
12+
void supervisor_stop_bluetooth_file_transfer(void);
13+
14+
void supervisor_bluetooth_file_transfer_background(void);
1315
void supervisor_bluetooth_file_transfer_disconnected(void);

supervisor/shared/bluetooth/serial.c

+5
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ void supervisor_stop_bluetooth_serial(void) {
148148
return;
149149
}
150150
common_hal_bleio_packet_buffer_flush(&_tx_packet_buffer);
151+
common_hal_bleio_packet_buffer_deinit(&_tx_packet_buffer);
152+
common_hal_bleio_characteristic_deinit(&supervisor_ble_circuitpython_rx_characteristic);
153+
common_hal_bleio_characteristic_deinit(&supervisor_ble_circuitpython_tx_characteristic);
154+
common_hal_bleio_characteristic_deinit(&supervisor_ble_circuitpython_version_characteristic);
155+
common_hal_bleio_service_deinit(&supervisor_ble_circuitpython_service);
151156
}
152157

153158
bool ble_serial_connected(void) {

supervisor/shared/usb/host_keyboard.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,9 @@ static void send_bufn_core(const char *buf, size_t n) {
155155
for (; n--; buf++) {
156156
int code = *buf;
157157
if (code == mp_interrupt_char) {
158+
ringbuf_clear(&_incoming_ringbuf);
158159
mp_sched_keyboard_interrupt();
159-
return;
160+
continue;
160161
}
161162
if (ringbuf_num_empty(&_incoming_ringbuf) == 0) {
162163
// Drop on the floor

supervisor/shared/web_workflow/websocket.c

+1
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ void websocket_background(void) {
227227
while (ringbuf_num_empty(&_incoming_ringbuf) > 0 &&
228228
_read_next_payload_byte(&c)) {
229229
if (c == mp_interrupt_char) {
230+
ringbuf_clear(&_incoming_ringbuf);
230231
mp_sched_keyboard_interrupt();
231232
continue;
232233
}

0 commit comments

Comments
 (0)