Fix crash when UART construct fails
After the script stops with the exception thrown the final gc_sweep will call any finalizers and they usually call deinit. deinit on invalid objects can wreak havoc by changing random memory or (hopefully) crashing. This fixes ensures the object is deinited until initialization succeeds and the object is valid. Do the same fix for I2C and SPI too. Fixes #4700 and fixes #5005
This commit is contained in:
parent
ce7301527a
commit
fece0fb432
@ -143,6 +143,10 @@ msgstr ""
|
||||
msgid "%q must be between %d and %d"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/busio/UART.c
|
||||
msgid "%q must be power of 2"
|
||||
msgstr ""
|
||||
|
||||
#: py/argcheck.c
|
||||
msgid "%q must of type %q"
|
||||
msgstr ""
|
||||
@ -389,6 +393,7 @@ msgstr ""
|
||||
msgid "All event channels in use"
|
||||
msgstr ""
|
||||
|
||||
#: ports/raspberrypi/common-hal/pulseio/PulseIn.c
|
||||
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
|
||||
msgid "All state machines in use"
|
||||
msgstr ""
|
||||
@ -973,7 +978,7 @@ msgstr ""
|
||||
msgid "Expected an alarm"
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/_pixelbuf/PixelBuf.c
|
||||
#: shared-module/adafruit_pixelbuf/PixelBuf.c
|
||||
#, c-format
|
||||
msgid "Expected tuple of length %d, got %d"
|
||||
msgstr ""
|
||||
@ -1295,7 +1300,7 @@ msgstr ""
|
||||
msgid "Invalid buffer size"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_pixelbuf/PixelBuf.c
|
||||
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
|
||||
msgid "Invalid byteorder string"
|
||||
msgstr ""
|
||||
|
||||
@ -1501,7 +1506,7 @@ msgstr ""
|
||||
msgid "Missing first_set_pin. Instruction %d sets pin(s)"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/displayio/Group.c
|
||||
#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c
|
||||
msgid "Must be a %q subclass."
|
||||
msgstr ""
|
||||
|
||||
@ -2348,7 +2353,7 @@ msgstr ""
|
||||
msgid "Unknown system firmware error: %04x"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_pixelbuf/PixelBuf.c
|
||||
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
|
||||
#, c-format
|
||||
msgid "Unmatched number of items on RHS (expected %d, got %d)."
|
||||
msgstr ""
|
||||
@ -2631,7 +2636,7 @@ msgstr ""
|
||||
msgid "buttons must be digitalio.DigitalInOut"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/_pixelbuf/PixelBuf.c
|
||||
#: shared-bindings/adafruit_pixelbuf/PixelBuf.c
|
||||
msgid "byteorder is not a string"
|
||||
msgstr ""
|
||||
|
||||
@ -2681,7 +2686,7 @@ msgid "can't cancel self"
|
||||
msgstr ""
|
||||
|
||||
#: py/obj.c py/objint.c shared-bindings/i2cperipheral/I2CPeripheral.c
|
||||
#: shared-module/_pixelbuf/PixelBuf.c
|
||||
#: shared-module/adafruit_pixelbuf/PixelBuf.c
|
||||
msgid "can't convert %q to %q"
|
||||
msgstr ""
|
||||
|
||||
|
@ -71,6 +71,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) {
|
||||
uint8_t sercom_index;
|
||||
uint32_t sda_pinmux, scl_pinmux;
|
||||
|
||||
// Ensure the object starts in its deinit state.
|
||||
self->sda_pin = NO_PIN;
|
||||
Sercom *sercom = samd_i2c_get_sercom(scl, sda, &sercom_index, &sda_pinmux, &scl_pinmux);
|
||||
if (sercom == NULL) {
|
||||
mp_raise_ValueError(translate("Invalid pins"));
|
||||
|
@ -92,6 +92,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
uint8_t miso_pad = 0;
|
||||
uint8_t dopo = 255;
|
||||
|
||||
// Ensure the object starts in its deinit state.
|
||||
self->clock_pin = NO_PIN;
|
||||
|
||||
// Special case for SAMR21 boards. (feather_radiofruit_zigbee)
|
||||
#if defined(PIN_PC19F_SERCOM4_PAD0)
|
||||
if (miso == &pin_PC19) {
|
||||
|
@ -71,6 +71,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
||||
uint32_t tx_pinmux = 0;
|
||||
uint8_t tx_pad = 255; // Unset pad
|
||||
|
||||
// Set state so the object is deinited to start.
|
||||
self->rx_pin = NO_PIN;
|
||||
self->tx_pin = NO_PIN;
|
||||
|
||||
if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) {
|
||||
mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
|
||||
}
|
||||
@ -85,6 +89,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
||||
mp_raise_ValueError(translate("tx and rx cannot both be None"));
|
||||
}
|
||||
|
||||
if (have_rx && receiver_buffer_size > 0 && (receiver_buffer_size & (receiver_buffer_size - 1)) != 0) {
|
||||
mp_raise_ValueError_varg(translate("%q must be power of 2"), MP_QSTR_receiver_buffer_size);
|
||||
}
|
||||
|
||||
self->baudrate = baudrate;
|
||||
self->character_bits = bits;
|
||||
self->timeout_ms = timeout * 1000;
|
||||
|
Loading…
x
Reference in New Issue
Block a user