diff options
| author | Scott Shawcroft <scott@tannewt.org> | 2018-08-08 21:36:33 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-08-08 21:36:33 -0700 |
| commit | cac760aa6f9ea5ddb6dba019dc9c3482bb3f4a79 (patch) | |
| tree | 8abe6541ce21ee97a806adc4f593ba58f9cabcdd | |
| parent | 2e80f37709c9fd7b168b684452ec436c24651973 (diff) | |
| parent | b0e33f6a116ac75c6a26216224182529db78e0a3 (diff) | |
Merge pull request #1080 from jepler/uart-ll
UART: Always allocate UART objects in the long-lived pool
| -rw-r--r-- | ports/atmel-samd/common-hal/busio/UART.c | 8 | ||||
| -rw-r--r-- | shared-bindings/busio/UART.c | 6 |
2 files changed, 12 insertions, 2 deletions
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index bcdeae7b5..20e662ec6 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -132,7 +132,13 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (rx && receiver_buffer_size > 0) { self->buffer_length = receiver_buffer_size; - self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, false); + // Initially allocate the UART's buffer in the long-lived part of the + // heap. UARTs are generally long-lived objects, but the "make long- + // lived" machinery is incapable of moving internal pointers like + // self->buffer, so do it manually. (However, as long as internal + // pointers like this are NOT moved, allocating the buffer + // in the long-lived pool is not strictly necessary) + self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false, true); if (self->buffer == NULL) { common_hal_busio_uart_deinit(self); mp_raise_msg(&mp_type_MemoryError, "Failed to allocate RX buffer"); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 1b63d8d0e..9bad2468e 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -66,7 +66,11 @@ extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); + // Always initially allocate the UART object within the long-lived heap. + // This is needed to avoid crashes with certain UART implementations which + // cannot accomodate being moved after creation. (See + // https://github.com/adafruit/circuitpython/issues/1056) + busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); self->base.type = &busio_uart_type; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); |
